diff --git a/src/gettime.h b/src/gettime.h
index 611906559b5059caf127553cd0f2954d8ea28fe0..cde1471e508541a2016b38284801ba3867826fe8 100644
--- a/src/gettime.h
+++ b/src/gettime.h
@@ -31,7 +31,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 		Normal build: main.cpp
 		Server build: servermain.cpp
 */
+enum TimePrecision {
+	PRECISION_SECONDS,
+	PRECISION_MILLI,
+	PRECISION_MICRO,
+	PRECISION_NANO
+};
+
 extern u32 getTimeMs();
+extern u32 getTime(TimePrecision prec);
 
 /*
 	Timestamp stuff
diff --git a/src/main.cpp b/src/main.cpp
index 1d625275758c70896d794370560c89cb30433f67..56c12585921524230ac9355b8335948b1ef49a78 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -133,7 +133,12 @@ MainGameCallback *g_gamecallback = NULL;
 u32 getTimeMs()
 {
 	/* Use imprecise system calls directly (from porting.h) */
-	return porting::getTimeMs();
+	return porting::getTime(PRECISION_MILLI);
+}
+
+u32 getTime(TimePrecision prec)
+{
+	return porting::getTime(prec);
 }
 
 #else
@@ -142,7 +147,7 @@ u32 getTimeMs()
 class TimeGetter
 {
 public:
-	virtual u32 getTime() = 0;
+	virtual u32 getTime(TimePrecision prec) = 0;
 };
 
 // A precise irrlicht one
@@ -152,11 +157,15 @@ class IrrlichtTimeGetter: public TimeGetter
 	IrrlichtTimeGetter(IrrlichtDevice *device):
 		m_device(device)
 	{}
-	u32 getTime()
+	u32 getTime(TimePrecision prec)
 	{
-		if(m_device == NULL)
-			return 0;
-		return m_device->getTimer()->getRealTime();
+		if (prec == PRECISION_MILLI) {
+			if(m_device == NULL)
+				return 0;
+			return m_device->getTimer()->getRealTime();
+		} else {
+			return porting::getTime(prec);
+		}
 	}
 private:
 	IrrlichtDevice *m_device;
@@ -165,9 +174,9 @@ class IrrlichtTimeGetter: public TimeGetter
 class SimpleTimeGetter: public TimeGetter
 {
 public:
-	u32 getTime()
+	u32 getTime(TimePrecision prec)
 	{
-		return porting::getTimeMs();
+		return porting::getTime(prec);
 	}
 };
 
@@ -179,7 +188,13 @@ u32 getTimeMs()
 {
 	if(g_timegetter == NULL)
 		return 0;
-	return g_timegetter->getTime();
+	return g_timegetter->getTime(PRECISION_MILLI);
+}
+
+u32 getTime(TimePrecision prec) {
+	if (g_timegetter == NULL)
+		return 0;
+	return g_timegetter->getTime(prec);
 }
 
 #endif
@@ -805,7 +820,7 @@ void SpeedTests()
 			}
 		}
 		// Do at least 10ms
-		while(timer.getTime() < 10);
+		while(timer.getTimerTime() < 10);
 
 		u32 dtime = timer.stop();
 		u32 per_ms = n / dtime;
diff --git a/src/porting.h b/src/porting.h
index d7d1073406e69a558d1452aa29b1e42e5178e374..bcce96ef7f0bbb092ffedd546ac7567ba1da69c2 100644
--- a/src/porting.h
+++ b/src/porting.h
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes.h" // u32
 #include "debug.h"
 #include "constants.h"
+#include "gettime.h"
 
 #ifdef _MSC_VER
 	#define SWPRINTF_CHARSTRING L"%S"
@@ -153,18 +154,65 @@ bool threadSetPriority(threadid_t tid, int prio);
 */
 #ifdef _WIN32 // Windows
 	#include <windows.h>
+	
+	inline u32 getTimeS()
+	{
+		return GetTickCount() / 1000;
+	}
+	
 	inline u32 getTimeMs()
 	{
 		return GetTickCount();
 	}
+	
+	inline u32 getTimeUs()
+	{
+		LARGE_INTEGER freq, t;
+		QueryPerformanceFrequency(&freq);
+		QueryPerformanceCounter(&t);
+		return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000.0);
+	}
+	
+	inline u32 getTimeNs()
+	{
+		LARGE_INTEGER freq, t;
+		QueryPerformanceFrequency(&freq);
+		QueryPerformanceCounter(&t);
+		return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000000.0);
+	}
+	
 #else // Posix
 	#include <sys/time.h>
+	#include <time.h>
+	
+	inline u32 getTimeS()
+	{
+		struct timeval tv;
+		gettimeofday(&tv, NULL);
+		return tv.tv_sec;
+	}
+	
 	inline u32 getTimeMs()
 	{
 		struct timeval tv;
 		gettimeofday(&tv, NULL);
 		return tv.tv_sec * 1000 + tv.tv_usec / 1000;
 	}
+	
+	inline u32 getTimeUs()
+	{
+		struct timeval tv;
+		gettimeofday(&tv, NULL);
+		return tv.tv_sec * 1000000 + tv.tv_usec;
+	}
+	
+	inline u32 getTimeNs()
+	{
+		struct timespec ts;
+		clock_gettime(CLOCK_REALTIME, &ts);
+		return ts.tv_sec * 1000000000 + ts.tv_nsec;
+	}
+	
 	/*#include <sys/timeb.h>
 	inline u32 getTimeMs()
 	{
@@ -174,6 +222,22 @@ bool threadSetPriority(threadid_t tid, int prio);
 	}*/
 #endif
 
+inline u32 getTime(TimePrecision prec)
+{
+	switch (prec) {
+		case PRECISION_SECONDS:
+			return getTimeS();
+		case PRECISION_MILLI:
+			return getTimeMs();
+		case PRECISION_MICRO:
+			return getTimeUs();
+		case PRECISION_NANO:
+			return getTimeNs();
+	}
+	return 0;
+}
+
+
 } // namespace porting
 
 #endif // PORTING_HEADER
diff --git a/src/util/timetaker.cpp b/src/util/timetaker.cpp
index 910fea822f89fe5ffd8338038d695e392f16f739..720a9e1a976e4a78ff1919caa08a74156f2ed776 100644
--- a/src/util/timetaker.cpp
+++ b/src/util/timetaker.cpp
@@ -23,19 +23,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "../log.h"
 #include <ostream>
 
-TimeTaker::TimeTaker(const char *name, u32 *result)
+TimeTaker::TimeTaker(const char *name, u32 *result, TimePrecision prec)
 {
 	m_name = name;
 	m_result = result;
 	m_running = true;
-	m_time1 = getTimeMs();
+	m_precision = prec;
+	m_time1 = getTime(prec);
 }
 
 u32 TimeTaker::stop(bool quiet)
 {
 	if(m_running)
 	{
-		u32 time2 = getTimeMs();
+		u32 time2 = getTime(m_precision);
 		u32 dtime = time2 - m_time1;
 		if(m_result != NULL)
 		{
@@ -52,9 +53,9 @@ u32 TimeTaker::stop(bool quiet)
 	return 0;
 }
 
-u32 TimeTaker::getTime()
+u32 TimeTaker::getTimerTime()
 {
-	u32 time2 = getTimeMs();
+	u32 time2 = getTime(m_precision);
 	u32 dtime = time2 - m_time1;
 	return dtime;
 }
diff --git a/src/util/timetaker.h b/src/util/timetaker.h
index 0b9d9ca04d2347d33bd4772147b93ad8a7e56821..5512c205fe611ab72263966bc1e3f5efb2c52fcf 100644
--- a/src/util/timetaker.h
+++ b/src/util/timetaker.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define UTIL_TIMETAKER_HEADER
 
 #include "../irrlichttypes.h"
+#include "../gettime.h"
 
 /*
 	TimeTaker
@@ -29,7 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class TimeTaker
 {
 public:
-	TimeTaker(const char *name, u32 *result=NULL);
+	TimeTaker(const char *name, u32 *result=NULL,
+		TimePrecision=PRECISION_MILLI);
 
 	~TimeTaker()
 	{
@@ -38,12 +40,13 @@ class TimeTaker
 
 	u32 stop(bool quiet=false);
 
-	u32 getTime();
+	u32 getTimerTime();
 
 private:
 	const char *m_name;
 	u32 m_time1;
 	bool m_running;
+	TimePrecision m_precision;
 	u32 *m_result;
 };