diff --git a/contrib/pgcrypto/fortuna.c b/contrib/pgcrypto/fortuna.c
index 5028203..1654c41 100644
--- a/contrib/pgcrypto/fortuna.c
+++ b/contrib/pgcrypto/fortuna.c
@@ -31,7 +31,6 @@
 
 #include "postgres.h"
 
-#include <sys/time.h>
 #include <time.h>
 
 #include "px.h"
@@ -89,8 +88,8 @@
  */
 #define NUM_POOLS		23
 
-/* in microseconds */
-#define RESEED_INTERVAL 100000	/* 0.1 sec */
+/* in nanoseconds */
+#define RESEED_INTERVAL 100000000	/* 0.1 sec */
 
 /* for one big request, reseed after this many bytes */
 #define RESEED_BYTES	(1024*1024)
@@ -123,7 +122,7 @@ struct fortuna_state
 	MD_CTX		pool[NUM_POOLS];
 	CIPH_CTX	ciph;
 	unsigned	reseed_count;
-	struct timeval last_reseed_time;
+	struct timespec last_reseed_time;
 	unsigned	pool0_bytes;
 	unsigned	rnd_pos;
 	int			tricks_done;
@@ -223,10 +222,10 @@ static int
 enough_time_passed(FState *st)
 {
 	int			ok;
-	struct timeval tv;
-	struct timeval *last = &st->last_reseed_time;
+	struct timespec tv;
+	struct timespec *last = &st->last_reseed_time;
 
-	gettimeofday(&tv, NULL);
+	clock_gettime(CLOCK_REALTIME, &tv);
 
 	/* check how much time has passed */
 	ok = 0;
@@ -234,10 +233,10 @@ enough_time_passed(FState *st)
 		ok = 1;
 	else if (tv.tv_sec == last->tv_sec + 1)
 	{
-		if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+		if (1000000000 + tv.tv_nsec - last->tv_nsec >= RESEED_INTERVAL)
 			ok = 1;
 	}
-	else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+	else if (tv.tv_nsec - last->tv_nsec >= RESEED_INTERVAL)
 		ok = 1;
 
 	/* reseed will happen, update last_reseed_time */
diff --git a/contrib/pgcrypto/random.c b/contrib/pgcrypto/random.c
index d72679e..34bf40e 100644
--- a/contrib/pgcrypto/random.c
+++ b/contrib/pgcrypto/random.c
@@ -162,7 +162,6 @@ try_win32_perfc(uint8 *dst)
 #define TRY_UNIXSTD
 
 #include <sys/types.h>
-#include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -178,7 +177,7 @@ try_unix_std(uint8 *dst)
 	pid_t		pid;
 	int			x;
 	PX_MD	   *md;
-	struct timeval tv;
+	struct timespec tv;
 	int			res;
 
 	/* process id */
@@ -187,7 +186,7 @@ try_unix_std(uint8 *dst)
 	dst += sizeof(pid);
 
 	/* time */
-	gettimeofday(&tv, NULL);
+	clock_gettime(CLOCK_REALTIME_COARSE, &tv);
 	memcpy(dst, (uint8 *) &tv, sizeof(tv));
 	dst += sizeof(tv);
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 2189c22..1e57a27 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4765,24 +4765,24 @@ BootStrapXLOG(void)
 	char	   *recptr;
 	bool		use_existent;
 	uint64		sysidentifier;
-	struct timeval tv;
+	struct timespec tv;
 	pg_crc32c	crc;
 
 	/*
 	 * Select a hopefully-unique system identifier code for this installation.
-	 * We use the result of gettimeofday(), including the fractional seconds
+	 * We use the result of clock_gettime(), including the fractional seconds
 	 * field, as being about as unique as we can easily get.  (Think not to
 	 * use random(), since it hasn't been seeded and there's no portable way
 	 * to seed it other than the system clock value...)  The upper half of the
 	 * uint64 value is just the tv_sec part, while the lower half contains the
-	 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
+	 * tv_nsec part (which must fit in 20 bits), plus 12 bits from our current
 	 * PID for a little extra uniqueness.  A person knowing this encoding can
 	 * determine the initialization time of the installation, which could
 	 * perhaps be useful sometimes.
 	 */
-	gettimeofday(&tv, NULL);
+	clock_gettime(CLOCK_REALTIME_COARSE, &tv);
 	sysidentifier = ((uint64) tv.tv_sec) << 32;
-	sysidentifier |= ((uint64) tv.tv_usec) << 12;
+	sysidentifier |= ((uint64) tv.tv_nsec) << 12;
 	sysidentifier |= getpid() & 0xFFF;
 
 	/* First timeline ID is always 1 */
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index d907e6b..d0652bb 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -19,6 +19,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "common/ip.h"
@@ -2434,7 +2435,7 @@ CheckRADIUSAuth(Port *port)
 	char		portstr[128];
 	ACCEPT_TYPE_ARG3 addrsize;
 	fd_set		fdset;
-	struct timeval endtime;
+	struct timespec endtime;
 	int			i,
 				j,
 				r;
@@ -2622,17 +2623,17 @@ CheckRADIUSAuth(Port *port)
 	 * the latch was set would improve the responsiveness to
 	 * timeouts/cancellations.
 	 */
-	gettimeofday(&endtime, NULL);
+	clock_gettime(CLOCK_REALTIME_COARSE, &endtime);
 	endtime.tv_sec += RADIUS_TIMEOUT;
 
 	while (true)
 	{
 		struct timeval timeout;
-		struct timeval now;
+		struct timespec now;
 		int64		timeoutval;
 
-		gettimeofday(&now, NULL);
-		timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
+		clock_gettime(CLOCK_REALTIME, &now);
+		timeoutval = (endtime.tv_sec * 1000000000 + endtime.tv_nsec) - (now.tv_sec * 1000000000 + now.tv_nsec);
 		if (timeoutval <= 0)
 		{
 			ereport(LOG,
@@ -2640,7 +2641,7 @@ CheckRADIUSAuth(Port *port)
 			closesocket(sock);
 			return STATUS_ERROR;
 		}
-		timeout.tv_sec = timeoutval / 1000000;
+		timeout.tv_sec = timeoutval / 10000000000;
 		timeout.tv_usec = timeoutval % 1000000;
 
 		FD_ZERO(&fdset);
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 1a92ca1..5b8cee0 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -290,7 +290,7 @@ NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_no
 
 static Oid	do_start_worker(void);
 static void launcher_determine_sleep(bool canlaunch, bool recursing,
-						 struct timeval * nap);
+						 struct timespec * nap);
 static void launch_worker(TimestampTz now);
 static List *get_database_list(void);
 static void rebuild_database_list(Oid newdb);
@@ -577,7 +577,7 @@ AutoVacLauncherMain(int argc, char *argv[])
 	/* loop until shutdown request */
 	while (!got_SIGTERM)
 	{
-		struct timeval nap;
+		struct timespec nap;
 		TimestampTz current_time = 0;
 		bool		can_launch;
 		int			rc;
@@ -598,7 +598,7 @@ AutoVacLauncherMain(int argc, char *argv[])
 		 */
 		rc = WaitLatch(MyLatch,
 					   WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-					   (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L));
+					   (nap.tv_sec * 1000L) + (nap.tv_nsec / 1000000L));
 
 		ResetLatch(MyLatch);
 
@@ -790,7 +790,7 @@ shutdown:
  * cause a long sleep, which will be interrupted when a worker exits.
  */
 static void
-launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
+launcher_determine_sleep(bool canlaunch, bool recursing, struct timespec * nap)
 {
 	/*
 	 * We sleep until the next scheduled vacuum.  We trust that when the
@@ -801,7 +801,7 @@ launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
 	if (!canlaunch)
 	{
 		nap->tv_sec = autovacuum_naptime;
-		nap->tv_usec = 0;
+		nap->tv_nsec = 0;
 	}
 	else if (!dlist_is_empty(&DatabaseList))
 	{
@@ -809,21 +809,21 @@ launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
 		TimestampTz next_wakeup;
 		avl_dbase  *avdb;
 		long		secs;
-		int			usecs;
+		int			nsecs;
 
 		avdb = dlist_tail_element(avl_dbase, adl_node, &DatabaseList);
 
 		next_wakeup = avdb->adl_next_worker;
-		TimestampDifference(current_time, next_wakeup, &secs, &usecs);
+		TimestampDifference(current_time, next_wakeup, &secs, &nsecs);
 
 		nap->tv_sec = secs;
-		nap->tv_usec = usecs;
+		nap->tv_nsec = nsecs;
 	}
 	else
 	{
 		/* list is empty, sleep for whole autovacuum_naptime seconds  */
 		nap->tv_sec = autovacuum_naptime;
-		nap->tv_usec = 0;
+		nap->tv_nsec = 0;
 	}
 
 	/*
@@ -836,7 +836,7 @@ launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
 	 * We only recurse once.  rebuild_database_list should always return times
 	 * in the future, but it seems best not to trust too much on that.
 	 */
-	if (nap->tv_sec == 0 && nap->tv_usec == 0 && !recursing)
+	if (nap->tv_sec == 0 && nap->tv_nsec == 0 && !recursing)
 	{
 		rebuild_database_list(InvalidOid);
 		launcher_determine_sleep(canlaunch, true, nap);
@@ -844,10 +844,10 @@ launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
 	}
 
 	/* The smallest time we'll allow the launcher to sleep. */
-	if (nap->tv_sec <= 0 && nap->tv_usec <= MIN_AUTOVAC_SLEEPTIME * 1000)
+	if (nap->tv_sec <= 0 && nap->tv_nsec <= MIN_AUTOVAC_SLEEPTIME * 1000000)
 	{
 		nap->tv_sec = 0;
-		nap->tv_usec = MIN_AUTOVAC_SLEEPTIME * 1000;
+		nap->tv_nsec = MIN_AUTOVAC_SLEEPTIME * 1000;
 	}
 
 	/*
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index d702a48..eb0668c 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -725,7 +725,7 @@ static bool
 IsCheckpointOnSchedule(double progress)
 {
 	XLogRecPtr	recptr;
-	struct timeval now;
+	struct timespec now;
 	double		elapsed_xlogs,
 				elapsed_time;
 
@@ -778,9 +778,9 @@ IsCheckpointOnSchedule(double progress)
 	/*
 	 * Check progress against time elapsed and checkpoint_timeout.
 	 */
-	gettimeofday(&now, NULL);
+	clock_gettime(CLOCK_REALTIME, &now);
 	elapsed_time = ((double) ((pg_time_t) now.tv_sec - ckpt_start_time) +
-					now.tv_usec / 1000000.0) / CheckPointTimeout;
+					now.tv_nsec / 1000000000.0) / CheckPointTimeout;
 
 	if (progress < elapsed_time)
 	{
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index eaf3f61..5277956 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -364,7 +364,7 @@ static volatile bool HaveCrashedWorker = false;
  * backend from the postmaster to that backend (via fork).
  */
 static unsigned int random_seed = 0;
-static struct timeval random_start_time;
+static struct timespec random_start_time;
 
 #ifdef USE_BONJOUR
 static DNSServiceRef bonjour_sdref = NULL;
@@ -1283,7 +1283,7 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	PgStartTime = GetCurrentTimestamp();
 	/* PostmasterRandom wants its own copy */
-	gettimeofday(&random_start_time, NULL);
+	clock_gettime(CLOCK_REALTIME, &random_start_time);
 
 	/*
 	 * We're ready to rock and roll...
@@ -4208,7 +4208,7 @@ BackendRun(Port *port)
 	 * a new random sequence in the random() library function.
 	 */
 	random_seed = 0;
-	random_start_time.tv_usec = 0;
+	random_start_time.tv_nsec = 0;
 	/* slightly hacky way to convert timestamptz into integers */
 	TimestampDifference(0, port->SessionStartTime, &secs, &usecs);
 	srandom((unsigned int) (MyProcPid ^ (usecs << 12) ^ secs));
@@ -5111,19 +5111,19 @@ PostmasterRandom(void)
 	{
 		do
 		{
-			struct timeval random_stop_time;
+			struct timespec random_stop_time;
 
-			gettimeofday(&random_stop_time, NULL);
+			clock_gettime(CLOCK_REALTIME, &random_stop_time);
 
 			/*
-			 * We are not sure how much precision is in tv_usec, so we swap
+			 * We are not sure how much precision is in tv_nsec, so we swap
 			 * the high and low 16 bits of 'random_stop_time' and XOR them
 			 * with 'random_start_time'. On the off chance that the result is
 			 * 0, we loop until it isn't.
 			 */
-			random_seed = random_start_time.tv_usec ^
-				((random_stop_time.tv_usec << 16) |
-				 ((random_stop_time.tv_usec >> 16) & 0xffff));
+			random_seed = random_start_time.tv_nsec ^
+				((random_stop_time.tv_nsec << 16) |
+				 ((random_stop_time.tv_nsec >> 16) & 0xffff));
 		}
 		while (random_seed == 0);
 
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 98ccbbb..6d6accb 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4374,13 +4374,13 @@ get_stack_depth_rlimit(void)
 
 
 static struct rusage Save_r;
-static struct timeval Save_t;
+static struct timespec Save_t;
 
 void
 ResetUsage(void)
 {
 	getrusage(RUSAGE_SELF, &Save_r);
-	gettimeofday(&Save_t, NULL);
+	clock_gettime(CLOCK_REALTIME, &Save_t);
 }
 
 void
@@ -4389,17 +4389,17 @@ ShowUsage(const char *title)
 	StringInfoData str;
 	struct timeval user,
 				sys;
-	struct timeval elapse_t;
+	struct timespec elapse_t;
 	struct rusage r;
 
 	getrusage(RUSAGE_SELF, &r);
-	gettimeofday(&elapse_t, NULL);
+	clock_gettime(CLOCK_REALTIME, &elapse_t);
 	memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
 	memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
-	if (elapse_t.tv_usec < Save_t.tv_usec)
+	if (elapse_t.tv_nsec < Save_t.tv_nsec)
 	{
 		elapse_t.tv_sec--;
-		elapse_t.tv_usec += 1000000;
+		elapse_t.tv_nsec += 1000000000;
 	}
 	if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
 	{
@@ -4425,7 +4425,7 @@ ShowUsage(const char *title)
 	appendStringInfo(&str,
 				"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
 					 (long) (elapse_t.tv_sec - Save_t.tv_sec),
-					 (long) (elapse_t.tv_usec - Save_t.tv_usec),
+					 (long) (elapse_t.tv_nsec - Save_t.tv_nsec),
 					 (long) (r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec),
 					 (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
 					 (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 224ee78..531aa69 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -147,7 +147,7 @@ static int	recursion_depth = 0;	/* to detect actual recursion */
  * Saved timeval and buffers for formatted timestamps that might be used by
  * both log_line_prefix and csv logs.
  */
-static struct timeval saved_timeval;
+static struct timespec saved_timeval;
 static bool saved_timeval_set = false;
 
 #define FORMATTED_TS_LEN 128
@@ -2232,7 +2232,7 @@ setup_formatted_log_time(void)
 
 	if (!saved_timeval_set)
 	{
-		gettimeofday(&saved_timeval, NULL);
+		clock_gettime(CLOCK_REALTIME_COARSE, &saved_timeval);
 		saved_timeval_set = true;
 	}
 
@@ -2249,7 +2249,7 @@ setup_formatted_log_time(void)
 				pg_localtime(&stamp_time, log_timezone));
 
 	/* 'paste' milliseconds into place... */
-	sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000));
+	sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_nsec / 1000000));
 	memcpy(formatted_log_time + 19, msbuf, 4);
 }
 
@@ -2480,12 +2480,12 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
 
 					if (!saved_timeval_set)
 					{
-						gettimeofday(&saved_timeval, NULL);
+						clock_gettime(CLOCK_REALTIME_COARSE, &saved_timeval);
 						saved_timeval_set = true;
 					}
 
 					sprintf(strfbuf, "%ld.%03d", saved_timeval.tv_sec,
-							(int) (saved_timeval.tv_usec / 1000));
+							(int) (saved_timeval.tv_nsec / 1000000));
 
 					if (padding != 0)
 						appendStringInfo(buf, "%*s", padding, strfbuf);
diff --git a/src/backend/utils/misc/pg_rusage.c b/src/backend/utils/misc/pg_rusage.c
index 8781a38..5242dad 100644
--- a/src/backend/utils/misc/pg_rusage.c
+++ b/src/backend/utils/misc/pg_rusage.c
@@ -27,7 +27,7 @@ void
 pg_rusage_init(PGRUsage *ru0)
 {
 	getrusage(RUSAGE_SELF, &ru0->ru);
-	gettimeofday(&ru0->tv, NULL);
+	clock_gettime(CLOCK_REALTIME, (struct timespec *)&ru0->tv);
 }
 
 /*
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index 595eaff..8481ec5 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <time.h>
 #include <unistd.h>
 
 /* for ntohl/htonl */
@@ -445,14 +446,14 @@ int64
 feGetCurrentTimestamp(void)
 {
 	int64		result;
-	struct timeval tp;
+	struct timespec tp;
 
-	gettimeofday(&tp, NULL);
+	clock_gettime(CLOCK_REALTIME_COARSE, &tp);
 
 	result = (int64) tp.tv_sec -
 		((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
 
-	result = (result * USECS_PER_SEC) + tp.tv_usec;
+	result = (result * NSECS_PER_SEC) + tp.tv_nsec;
 
 	return result;
 }
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index ba9c276..9fc3a82 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1756,7 +1756,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
 		 * Further discussion ensued, and the proposal was dropped.
 		 *
 		 * For those people who want this feature, it can be implemented using
-		 * gettimeofday in each loop, calculating the time since last sleep,
+		 * clock_gettime in each loop, calculating the time since last sleep,
 		 * multiplying that by the sleep ratio, then if the result is more
 		 * than a preset 'minimum sleep time' (say 100ms), call the 'select'
 		 * function to sleep for a subsecond period ie.
@@ -1764,7 +1764,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
 		 * select(0, NULL, NULL, NULL, &tvi);
 		 *
 		 * This will return after the interval specified in the structure tvi.
-		 * Finally, call gettimeofday again to save the 'last sleep time'.
+		 * Finally, call clock_gettime again to save the 'last sleep time'.
 		 * ----------
 		 */
 	}
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 525b82ba..cc9b03e 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -535,7 +535,7 @@ static void
 GuessControlValues(void)
 {
 	uint64		sysidentifier;
-	struct timeval tv;
+	struct timespec tv;
 
 	/*
 	 * Set up a completely default set of pg_control values.
@@ -550,9 +550,9 @@ GuessControlValues(void)
 	 * Create a new unique installation identifier, since we can no longer use
 	 * any old XLOG records.  See notes in xlog.c about the algorithm.
 	 */
-	gettimeofday(&tv, NULL);
+	clock_gettime(CLOCK_REALTIME_COARSE, &tv);
 	sysidentifier = ((uint64) tv.tv_sec) << 32;
-	sysidentifier |= ((uint64) tv.tv_usec) << 12;
+	sysidentifier |= ((uint64) tv.tv_nsec) << 12;
 	sysidentifier |= getpid() & 0xFFF;
 
 	ControlFile.system_identifier = sysidentifier;
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index c842762..ca8206e 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -26,7 +26,7 @@
 #define LABEL_FORMAT		"        %-30s"
 #define NA_FORMAT			"%20s"
 #define OPS_FORMAT			"%13.3f ops/sec  %6.0f usecs/op"
-#define USECS_SEC			1000000
+#define NSECS_SEC			1000000000
 
 /* These are macros to avoid timing the function call overhead. */
 #ifndef WIN32
@@ -34,7 +34,7 @@
 do { \
 	alarm_triggered = false; \
 	alarm(secs_per_test); \
-	gettimeofday(&start_t, NULL); \
+	clock_gettime(CLOCK_REALTIME, &start_t); \
 } while (0)
 #else
 /* WIN32 doesn't support alarm, so we create a thread and sleep there */
@@ -47,13 +47,13 @@ do { \
 		fprintf(stderr, "Cannot create thread for alarm\n"); \
 		exit(1); \
 	} \
-	gettimeofday(&start_t, NULL); \
-} while (0)
+	clock_gettime(CLOCK_REALTIME, &start_t); \
+	} while (0)
 #endif
 
 #define STOP_TIMER	\
 do { \
-	gettimeofday(&stop_t, NULL); \
+	clock_gettime(CLOCK_REALTIME, &stop_t); \
 	print_elapse(start_t, stop_t, ops); \
 } while (0)
 
@@ -65,7 +65,7 @@ static int	needs_unlink = 0;
 static char full_buf[XLOG_SEG_SIZE],
 		   *buf,
 		   *filename = FSYNC_FILENAME;
-static struct timeval start_t,
+static struct timespec start_t,
 			stop_t;
 static bool alarm_triggered = false;
 
@@ -89,7 +89,7 @@ static void signal_cleanup(int sig);
 #ifdef HAVE_FSYNC_WRITETHROUGH
 static int	pg_fsync_writethrough(int fd);
 #endif
-static void print_elapse(struct timeval start_t, struct timeval stop_t, int ops);
+static void print_elapse(struct timespec start_t, struct timespec stop_t, int ops);
 static void die(const char *str);
 
 
@@ -568,12 +568,12 @@ pg_fsync_writethrough(int fd)
  * print out the writes per second for tests
  */
 static void
-print_elapse(struct timeval start_t, struct timeval stop_t, int ops)
+print_elapse(struct timespec start_t, struct timespec stop_t, int ops)
 {
 	double		total_time = (stop_t.tv_sec - start_t.tv_sec) +
-	(stop_t.tv_usec - start_t.tv_usec) * 0.000001;
+	(stop_t.tv_nsec - start_t.tv_nsec) * 0.000000001;
 	double		per_second = ops / total_time;
-	double		avg_op_time_us = (total_time / ops) * USECS_SEC;
+	double		avg_op_time_us = (total_time / ops) * NSECS_SEC;
 
 	printf(OPS_FORMAT "\n", per_second, avg_op_time_us);
 }
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 56c37d5..d10fe51 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1772,7 +1772,7 @@ doCustom(TState *thread, CState *st, StatsData *agg)
 	instr_time	now;
 
 	/*
-	 * gettimeofday() isn't free, so we get the current timestamp lazily the
+	 * clock_gettime() isn't free, so we get the current timestamp lazily the
 	 * first time it's needed, and reuse the same value throughout this
 	 * function after that. This also ensures that e.g. the calculated latency
 	 * reported in the log file and in the totals are the same. Zero means
@@ -2247,11 +2247,11 @@ doLog(TState *thread, CState *st, instr_time *now,
 		if (skipped)
 			fprintf(logfile, "%d " INT64_FORMAT " skipped %d %ld %ld",
 					st->id, st->cnt, st->use_file,
-					(long) now->tv_sec, (long) now->tv_usec);
+					(long) now->tv_sec, (long) now->tv_nsec);
 		else
 			fprintf(logfile, "%d " INT64_FORMAT " %.0f %d %ld %ld",
 					st->id, st->cnt, latency, st->use_file,
-					(long) now->tv_sec, (long) now->tv_usec);
+					(long) now->tv_sec, (long) now->tv_nsec);
 #else
 
 		/* On Windows, instr_time doesn't provide a timestamp anyway */
diff --git a/src/include/c.h b/src/include/c.h
index 4ab3f80..020fa30 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -138,6 +138,16 @@
  */
 #define gettext_noop(x) (x)
 
+#if defined(WIN32) || defined(__CYGWIN__)
+typedef struct timespec {
+	long tv_sec;
+	long tv_nsec;
+} timespec;
+
+#define CLOCK_REALTIME 1
+#define CLOCK_REALTIME_COARSE 2
+#endif
+
 
 /* ----------------------------------------------------------------
  *				Section 1: hacks to cope with non-ANSI C compilers
diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h
index 68a41eb..31d39d8 100644
--- a/src/include/datatype/timestamp.h
+++ b/src/include/datatype/timestamp.h
@@ -105,6 +105,9 @@ typedef struct
 #define USECS_PER_MINUTE INT64CONST(60000000)
 #define USECS_PER_SEC	INT64CONST(1000000)
 
+#define NSECS_PER_SEC	INT64CONST(1000000000)
+#define NSECS_PER_USEC	INT64CONST(1000)
+
 /*
  * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich.
  * Currently, the record holders for wackiest offsets in actual use are zones
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b621ff2..e2efae7 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -231,6 +231,9 @@
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME 
+
 /* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 #undef HAVE_GSSAPI_GSSAPI_H
 
diff --git a/src/include/port.h b/src/include/port.h
index b81fa4a..a8e80dc 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -319,6 +319,11 @@ extern FILE *pgwin32_popen(const char *command, const char *type);
 /* Last parameter not used */
 extern int	gettimeofday(struct timeval * tp, struct timezone * tzp);
 #endif
+/* New versions of MingW have gettimeofday, old mingw and msvc don't */
+#ifndef HAVE_CLOCK_GETTIME
+/* First parameter is not used */
+extern int	clock_gettime(int clock_id, struct timespec * tp);
+#endif
 #else							/* !WIN32 */
 
 /*
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index 16caf6e..ebcc976 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -4,7 +4,7 @@
  *	  portable high-precision interval timing
  *
  * This file provides an abstraction layer to hide portability issues in
- * interval timing.  On Unix we use gettimeofday(), but on Windows that
+ * interval timing.  On Unix we use clock_gettime(), but on Windows that
  * gives a low-precision result so we must use QueryPerformanceCounter()
  * instead.  These macros also give some breathing room to use other
  * high-precision-timing APIs on yet other platforms.
@@ -54,24 +54,24 @@
 
 #ifndef WIN32
 
-#include <sys/time.h>
+#include <time.h>
 
-typedef struct timeval instr_time;
+typedef struct timespec instr_time;
 
-#define INSTR_TIME_IS_ZERO(t)	((t).tv_usec == 0 && (t).tv_sec == 0)
+#define INSTR_TIME_IS_ZERO(t)	((t).tv_nsec == 0 && (t).tv_sec == 0)
 
-#define INSTR_TIME_SET_ZERO(t)	((t).tv_sec = 0, (t).tv_usec = 0)
+#define INSTR_TIME_SET_ZERO(t)	((t).tv_sec = 0, (t).tv_nsec = 0)
 
-#define INSTR_TIME_SET_CURRENT(t)	gettimeofday(&(t), NULL)
+#define INSTR_TIME_SET_CURRENT(t)	clock_gettime(CLOCK_REALTIME, &(t))
 
 #define INSTR_TIME_ADD(x,y) \
 	do { \
 		(x).tv_sec += (y).tv_sec; \
-		(x).tv_usec += (y).tv_usec; \
+		(x).tv_nsec += (y).tv_nsec; \
 		/* Normalize */ \
-		while ((x).tv_usec >= 1000000) \
+		while ((x).tv_nsec >= 1000000000) \
 		{ \
-			(x).tv_usec -= 1000000; \
+			(x).tv_nsec -= 1000000000; \
 			(x).tv_sec++; \
 		} \
 	} while (0)
@@ -79,11 +79,11 @@ typedef struct timeval instr_time;
 #define INSTR_TIME_SUBTRACT(x,y) \
 	do { \
 		(x).tv_sec -= (y).tv_sec; \
-		(x).tv_usec -= (y).tv_usec; \
+		(x).tv_nsec -= (y).tv_nsec; \
 		/* Normalize */ \
-		while ((x).tv_usec < 0) \
+		while ((x).tv_nsec < 0) \
 		{ \
-			(x).tv_usec += 1000000; \
+			(x).tv_nsec += 1000000000; \
 			(x).tv_sec--; \
 		} \
 	} while (0)
@@ -91,28 +91,28 @@ typedef struct timeval instr_time;
 #define INSTR_TIME_ACCUM_DIFF(x,y,z) \
 	do { \
 		(x).tv_sec += (y).tv_sec - (z).tv_sec; \
-		(x).tv_usec += (y).tv_usec - (z).tv_usec; \
+		(x).tv_nsec += (y).tv_nsec - (z).tv_nsec; \
 		/* Normalize after each add to avoid overflow/underflow of tv_usec */ \
-		while ((x).tv_usec < 0) \
+		while ((x).tv_nsec < 0) \
 		{ \
-			(x).tv_usec += 1000000; \
+			(x).tv_nsec += 1000000000; \
 			(x).tv_sec--; \
 		} \
-		while ((x).tv_usec >= 1000000) \
+		while ((x).tv_nsec >= 1000000000) \
 		{ \
-			(x).tv_usec -= 1000000; \
+			(x).tv_nsec -= 1000000; \
 			(x).tv_sec++; \
 		} \
 	} while (0)
 
 #define INSTR_TIME_GET_DOUBLE(t) \
-	(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
+	(((double) (t).tv_sec) + ((double) (t).tv_nsec) / 1000000000.0)
 
 #define INSTR_TIME_GET_MILLISEC(t) \
-	(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
+	(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_nsec) / 1000000.0)
 
 #define INSTR_TIME_GET_MICROSEC(t) \
-	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
+	(((uint64) (t).tv_sec * (uint64) 1000000) + ((double) (t).tv_nsec) / 1000.0)
 #else							/* WIN32 */
 
 typedef LARGE_INTEGER instr_time;
diff --git a/src/include/utils/pg_rusage.h b/src/include/utils/pg_rusage.h
index 7c264eb..9ca9436 100644
--- a/src/include/utils/pg_rusage.h
+++ b/src/include/utils/pg_rusage.h
@@ -15,6 +15,7 @@
 #define PG_RUSAGE_H
 
 #include <sys/time.h>
+#include <time.h>
 
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
diff --git a/src/port/clock_gettime.c b/src/port/clock_gettime.c
new file mode 100644
index 0000000..05641ad
--- /dev/null
+++ b/src/port/clock_gettime.c
@@ -0,0 +1,117 @@
+/*
+ * clock_gettime.c
+ *	  Win32 clock_gettime() replacement
+ *
+ * src/port/clock_gettime.c
+ *
+ * Copyright (c) 2003 SRA, Inc.
+ * Copyright (c) 2003 SKC, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without a
+ * written agreement is hereby granted, provided that the above
+ * copyright notice and this paragraph and the following two
+ * paragraphs appear in all copies.
+ *
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
+ * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
+ * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "c.h"
+
+#include <time.h>
+
+/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
+static const unsigned __int64 epoch = UINT64CONST(116444736000000000);
+
+/*
+ * FILETIME represents the number of 100-nanosecond intervals since
+ * January 1, 1601 (UTC).
+ */
+#define FILETIME_UNITS_PER_SEC	10000000L
+#define FILETIME_UNITS_PER_USEC 10
+
+/*
+ * Both GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime share a
+ * signature, so we can just store a pointer to whichever we find. This
+ * is the pointer's type.
+ */
+typedef		VOID(WINAPI * PgGetSystemTimeFn) (LPFILETIME);
+
+/* One-time initializer function, must match that signature. */
+static void WINAPI init_clock_gettime(LPFILETIME lpSystemTimeAsFileTime);
+
+/* Storage for the function we pick at runtime */
+static PgGetSystemTimeFn pg_get_system_time = &init_clock_gettime;
+
+/*
+ * One time initializer.  Determine whether GetSystemTimePreciseAsFileTime
+ * is available and if so, plan to use it; if not, fall back to
+ * GetSystemTimeAsFileTime.
+ */
+static void WINAPI
+init_clock_gettime(LPFILETIME lpSystemTimeAsFileTime)
+{
+	/*
+	 * Because it's guaranteed that kernel32.dll will be linked into our
+	 * address space already, we don't need to LoadLibrary it and worry about
+	 * closing it afterwards, so we're not using Pg's dlopen/dlsym() wrapper.
+	 *
+	 * We'll just look up the address of GetSystemTimePreciseAsFileTime if
+	 * present.
+	 *
+	 * While we could look up the Windows version and skip this on Windows
+	 * versions below Windows 8 / Windows Server 2012 there isn't much point,
+	 * and determining the windows version is its self somewhat Windows
+	 * version and development SDK specific...
+	 */
+	pg_get_system_time = (PgGetSystemTimeFn) GetProcAddress(
+									   GetModuleHandle(TEXT("kernel32.dll")),
+										   "GetSystemTimePreciseAsFileTime");
+	if (pg_get_system_time == NULL)
+	{
+		/*
+		 * The expected error from GetLastError() is ERROR_PROC_NOT_FOUND, if
+		 * the function isn't present. No other error should occur.
+		 *
+		 * We can't report an error here because this might be running in
+		 * frontend code; and even if we're in the backend, it's too early to
+		 * elog(...) if we get some unexpected error.  Also, it's not a
+		 * serious problem, so just silently fall back to
+		 * GetSystemTimeAsFileTime irrespective of why the failure occurred.
+		 */
+		pg_get_system_time = &GetSystemTimeAsFileTime;
+	}
+
+	(*pg_get_system_time) (lpSystemTimeAsFileTime);
+}
+
+/*
+ * Note: this function is not for Win32 high precision timing purposes. See
+ * elapsed_time().
+ */
+int
+clock_gettime(int clock_id, struct timespec * tp)
+{
+	FILETIME	file_time;
+	ULARGE_INTEGER ularge;
+
+	(*pg_get_system_time) (&file_time);
+	ularge.LowPart = file_time.dwLowDateTime;
+	ularge.HighPart = file_time.dwHighDateTime;
+
+	tp->tv_sec = (long) ((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
+	tp->tv_nsec = (long) ((((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC)
+						  / FILETIME_UNITS_PER_USEC) * 1000);
+
+	return 0;
+}
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index db2b559..d31aef5 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -11,6 +11,7 @@
 #include <windows.h>
 #endif
 #include <sys/time.h>
+#include <time.h>
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
@@ -698,7 +699,7 @@ try_complete_step(Step *step, int flags)
 {
 	PGconn	   *conn = conns[1 + step->session];
 	fd_set		read_set;
-	struct timeval start_time;
+	struct timespec start_time;
 	struct timeval timeout;
 	int			sock = PQsocket(conn);
 	int			ret;
@@ -711,7 +712,7 @@ try_complete_step(Step *step, int flags)
 		exit_nicely();
 	}
 
-	gettimeofday(&start_time, NULL);
+	clock_gettime(CLOCK_REALTIME, &start_time);
 	FD_ZERO(&read_set);
 
 	while (PQisBusy(conn))
@@ -730,7 +731,7 @@ try_complete_step(Step *step, int flags)
 		}
 		else if (ret == 0)		/* select() timeout: check for lock wait */
 		{
-			struct timeval current_time;
+			struct timespec current_time;
 			int64		td;
 
 			/* If it's OK for the step to block, check whether it has. */
@@ -762,10 +763,10 @@ try_complete_step(Step *step, int flags)
 			}
 
 			/* Figure out how long we've been waiting for this step. */
-			gettimeofday(&current_time, NULL);
+			clock_gettime(CLOCK_REALTIME, &current_time);
 			td = (int64) current_time.tv_sec - (int64) start_time.tv_sec;
-			td *= USECS_PER_SEC;
-			td += (int64) current_time.tv_usec - (int64) start_time.tv_usec;
+			td *= NSECS_PER_SEC;
+			td += (int64) current_time.tv_nsec - (int64) start_time.tv_nsec;
 
 			/*
 			 * After 60 seconds, try to cancel the query.
@@ -776,7 +777,7 @@ try_complete_step(Step *step, int flags)
 			 * presumably lead to this permutation failing, but remaining
 			 * permutations and tests should still be OK.
 			 */
-			if (td > 60 * USECS_PER_SEC && !canceled)
+			if (td > 60 * NSECS_PER_SEC && !canceled)
 			{
 				PGcancel   *cancel = PQgetCancel(conn);
 
@@ -799,7 +800,7 @@ try_complete_step(Step *step, int flags)
 			 * later tests to fail.  That stinks, but it's better than waiting
 			 * forever for the server to respond to the cancel.
 			 */
-			if (td > 75 * USECS_PER_SEC)
+			if (td > 75 * NSECS_PER_SEC)
 			{
 				fprintf(stderr, "step %s timed out after 75 seconds\n",
 						step->name);
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 93dfd24..1b16684 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -88,8 +88,8 @@ sub mkvcbuild
 	$solution = CreateSolution($vsVersion, $config);
 
 	our @pgportfiles = qw(
-	  chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c
-	  srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
+	  chklocale.c clock_gettime.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c
+	  random.c srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c
 	  mkdtemp.c qsort.c qsort_arg.c quotes.c system.c
