1633838b8255282d10af15c5c84cee5a51466712Bob Halley/*
09b9db3c91786130fc095df5055098964e7cdb83Tinderbox User * Copyright (C) 1998-2001, 2003, 2004, 2006-2009, 2012-2018 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley */
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
ece6c39dd823d92cf89e7e37614bd458d5d42658Mark Andrews/* $Id: time.c,v 1.52 2009/08/14 07:51:08 marka Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley#include <config.h>
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence#include <errno.h>
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence#include <limits.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <stddef.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <stdlib.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <string.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <time.h>
9fbefe0ace2ae7dba287f914b278153004bef428Bob Halley
9fbefe0ace2ae7dba287f914b278153004bef428Bob Halley#include <windows.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <isc/assertions.h>
cd320a8d235dc1b488e46affc918cba61fa69b1eMark Andrews#include <isc/string.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley#include <isc/time.h>
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt#include <isc/tm.h>
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer#include <isc/util.h>
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence/*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * struct FILETIME uses "100-nanoseconds intervals".
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence * NS / S = 1000000000 (10^9).
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence * While it is reasonably obvious that this makes the needed
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence * conversion factor 10^7, it is coded this way for additional clarity.
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence */
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence#define NS_PER_S 1000000000
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence#define NS_INTERVAL 100
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence#define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer#define UINT64_MAX _UI64_MAX
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer/***
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer *** Absolute Times
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer ***/
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsstatic const isc_time_t epoch = { { 0, 0 } };
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark AndrewsLIBISC_EXTERNAL_DATA const isc_time_t * const isc_time_epoch = &epoch;
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley/***
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley *** Intervals
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley ***/
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsstatic const isc_interval_t zero_interval = { 0 };
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark AndrewsLIBISC_EXTERNAL_DATA const isc_interval_t * const isc_interval_zero = &zero_interval;
ea872078bfa9473cfe9c89b474dae2496377797bDavid Lawrence
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleyvoid
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafssonisc_interval_set(isc_interval_t *i, unsigned int seconds,
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson unsigned int nanoseconds)
e76d4c91bfadf823f04dcca1c1c5bcc14c67671dAndreas Gustafsson{
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(i != NULL);
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer REQUIRE(nanoseconds < NS_PER_S);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews /*
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews * This rounds nanoseconds up not down.
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews */
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence i->interval = (LONGLONG)seconds * INTERVALS_PER_S
e72c1e7e465822fc9b5067b2dd3cf047f6132214Mark Andrews + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL;
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley}
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleyisc_boolean_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_interval_iszero(const isc_interval_t *i) {
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(i != NULL);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley if (i->interval == 0)
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley return (ISC_TRUE);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley return (ISC_FALSE);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley}
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrewsvoid
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrewsisc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont SYSTEMTIME epoch1970 = { 1970, 1, 4, 1, 0, 0, 0, 0 };
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews FILETIME temp;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews ULARGE_INTEGER i1;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews REQUIRE(t != NULL);
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews REQUIRE(nanoseconds < NS_PER_S);
e2c97aef510f4cdced2894ab2a5daf2b1d316e2aAutomatic Updater
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont SystemTimeToFileTime(&epoch1970, &temp);
e2c97aef510f4cdced2894ab2a5daf2b1d316e2aAutomatic Updater
dc1cfff92a77c5b47e5665a3c2f0153d79074f47Evan Hunt i1.LowPart = temp.dwLowDateTime;
dc1cfff92a77c5b47e5665a3c2f0153d79074f47Evan Hunt i1.HighPart = temp.dwHighDateTime;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews i1.QuadPart += (unsigned __int64)nanoseconds/100;
ed9ca2306508e3106e3d111d7cf39bf82f8689d0Mark Andrews i1.QuadPart += (unsigned __int64)seconds*10000000;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews t->absolute.dwLowDateTime = i1.LowPart;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews t->absolute.dwHighDateTime = i1.HighPart;
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews}
8343d55b3d97923fa444ea9b92aae2ec60ffd40fMark Andrews
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleyvoid
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrenceisc_time_settoepoch(isc_time_t *t) {
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(t != NULL);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson t->absolute.dwLowDateTime = 0;
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson t->absolute.dwHighDateTime = 0;
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley}
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleyisc_boolean_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_isepoch(const isc_time_t *t) {
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(t != NULL);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson if (t->absolute.dwLowDateTime == 0 &&
355cc22e32085faeb553fe6c37de69e83b9d5191Andreas Gustafsson t->absolute.dwHighDateTime == 0)
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley return (ISC_TRUE);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley return (ISC_FALSE);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley}
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrenceisc_result_t
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrenceisc_time_now(isc_time_t *t) {
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley REQUIRE(t != NULL);
9fbefe0ace2ae7dba287f914b278153004bef428Bob Halley
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley GetSystemTimeAsFileTime(&t->absolute);
9fbefe0ace2ae7dba287f914b278153004bef428Bob Halley
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley return (ISC_R_SUCCESS);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley}
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrenceisc_result_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence ULARGE_INTEGER i1;
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence REQUIRE(t != NULL);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence REQUIRE(i != NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence GetSystemTimeAsFileTime(&t->absolute);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence i1.LowPart = t->absolute.dwLowDateTime;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence i1.HighPart = t->absolute.dwHighDateTime;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence i1.QuadPart += i->interval;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence t->absolute.dwLowDateTime = i1.LowPart;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence t->absolute.dwHighDateTime = i1.HighPart;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence return (ISC_R_SUCCESS);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence}
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrenceint
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley REQUIRE(t1 != NULL && t2 != NULL);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley return ((int)CompareFileTime(&t1->absolute, &t2->absolute));
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley}
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_result_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafsson{
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence ULARGE_INTEGER i1;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(t != NULL && i != NULL && result != NULL);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i1.LowPart = t->absolute.dwLowDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i1.HighPart = t->absolute.dwHighDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence i1.QuadPart += i->interval;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence result->absolute.dwLowDateTime = i1.LowPart;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence result->absolute.dwHighDateTime = i1.HighPart;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_SUCCESS);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley}
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_result_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafsson isc_time_t *result) {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence ULARGE_INTEGER i1;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley REQUIRE(t != NULL && i != NULL && result != NULL);
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i1.LowPart = t->absolute.dwLowDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i1.HighPart = t->absolute.dwHighDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer if (i1.QuadPart < (unsigned __int64) i->interval)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence i1.QuadPart -= i->interval;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence result->absolute.dwLowDateTime = i1.LowPart;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence result->absolute.dwHighDateTime = i1.HighPart;
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer
e35c1bb3ecd9a6597360b9160b397c8053af69bfDanny Mayer return (ISC_R_SUCCESS);
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley}
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
d3e7d196cd14fc3095ce97846a66cd49fc6fee6dDavid Lawrenceisc_uint64_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence ULARGE_INTEGER i1, i2;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley LONGLONG i3;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence REQUIRE(t1 != NULL && t2 != NULL);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence i1.LowPart = t1->absolute.dwLowDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i1.HighPart = t1->absolute.dwHighDateTime;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence i2.LowPart = t2->absolute.dwLowDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley i2.HighPart = t2->absolute.dwHighDateTime;
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley if (i1.QuadPart <= i2.QuadPart)
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley return (0);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence /*
d3e7d196cd14fc3095ce97846a66cd49fc6fee6dDavid Lawrence * Convert to microseconds.
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence */
d3e7d196cd14fc3095ce97846a66cd49fc6fee6dDavid Lawrence i3 = (i1.QuadPart - i2.QuadPart) / 10;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence
d3e7d196cd14fc3095ce97846a66cd49fc6fee6dDavid Lawrence return (i3);
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley}
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrewsisc_uint32_t
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrewsisc_time_seconds(const isc_time_t *t) {
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont SYSTEMTIME epoch1970 = { 1970, 1, 4, 1, 0, 0, 0, 0 };
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews FILETIME temp;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews ULARGE_INTEGER i1, i2;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews LONGLONG i3;
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont SystemTimeToFileTime(&epoch1970, &temp);
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i1.LowPart = t->absolute.dwLowDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i1.HighPart = t->absolute.dwHighDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i2.LowPart = temp.dwLowDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i2.HighPart = temp.dwHighDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i3 = (i1.QuadPart - i2.QuadPart) / 10000000;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews
ece6c39dd823d92cf89e7e37614bd458d5d42658Mark Andrews return ((isc_uint32_t)i3);
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews}
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Huntisc_result_t
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Huntisc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) {
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt time_t seconds;
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt REQUIRE(t != NULL);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt seconds = (time_t)isc_time_seconds(t);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t));
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt INSIST(sizeof(time_t) >= sizeof(isc_uint32_t));
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
f459b70c8ea8fb7aed93ff3b3104b837e009c6fdEvan Hunt if (isc_time_seconds(t) > (~0U>>1) && seconds <= (time_t)(~0U>>1))
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt return (ISC_R_RANGE);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt *secondsp = seconds;
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt return (ISC_R_SUCCESS);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt}
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrenceisc_uint32_t
6c6ceac1bc66812f6e0097dcf5fd8b901c3fecd1Andreas Gustafssonisc_time_nanoseconds(const isc_time_t *t) {
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews ULARGE_INTEGER i;
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i.LowPart = t->absolute.dwLowDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews i.HighPart = t->absolute.dwHighDateTime;
1d9958c6cc291916010779792f0fbdf6cd5ba368Mark Andrews return ((isc_uint32_t)(i.QuadPart % 10000000) * 100);
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence}
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafssonvoid
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafssonisc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson FILETIME localft;
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson SYSTEMTIME st;
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson char DateBuf[50];
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson char TimeBuf[50];
6ebd91a0c7f4c62a501b67adce4a6800d8b7dfacAutomatic Updater
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson REQUIRE(len > 0);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson if (FileTimeToLocalFileTime(&t->absolute, &localft) &&
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson FileTimeToSystemTime(&localft, &st)) {
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy",
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews DateBuf, 50);
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER|
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50);
6ebd91a0c7f4c62a501b67adce4a6800d8b7dfacAutomatic Updater
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf,
b38ab99bdc833da490c0ca0cbd05fb9d54dff997Andreas Gustafsson st.wMilliseconds);
6ebd91a0c7f4c62a501b67adce4a6800d8b7dfacAutomatic Updater
a6f0e9c985220f0e4509777e6528afb64e0ad576Mukund Sivaraman } else {
5a93d3be4e0c652f455066bb764416173a00c951Mark Andrews strlcpy(buf, "99-Bad-9999 99:99:99.999", len);
a6f0e9c985220f0e4509777e6528afb64e0ad576Mukund Sivaraman }
ff8cd3afa7f900d7986ccbc3638235cb8ad6f1ecAndreas Gustafsson}
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsvoid
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsisc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews SYSTEMTIME st;
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews char DateBuf[50];
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews char TimeBuf[50];
6ebd91a0c7f4c62a501b67adce4a6800d8b7dfacAutomatic Updater
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt/* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews REQUIRE(len > 0);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (FileTimeToSystemTime(&t->absolute, &st)) {
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt GetDateFormat(LOCALE_USER_DEFAULT, 0, &st,
99bf6a57d9f6b55da6de9c22fb6883a4bf7d569eEvan Hunt "ddd',' dd MMM yyyy", DateBuf, 50);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews GetTimeFormat(LOCALE_USER_DEFAULT,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews &st, "hh':'mm':'ss", TimeBuf, 50);
6ebd91a0c7f4c62a501b67adce4a6800d8b7dfacAutomatic Updater
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews } else {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews buf[0] = 0;
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews }
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews}
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Huntisc_result_t
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Huntisc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt struct tm t_tm;
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt time_t when;
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt char *p;
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt REQUIRE(buf != NULL);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt if (p == NULL)
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt return (ISC_R_UNEXPECTED);
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt when = isc_tm_timegm(&t_tm);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt if (when == -1)
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt return (ISC_R_UNEXPECTED);
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt isc_time_set(t, (unsigned int)when, 0);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt return (ISC_R_SUCCESS);
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt}
1bb2f53b9f74a8ca9812cbe9243ef41190b4da14Evan Hunt
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Huntvoid
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Huntisc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt SYSTEMTIME st;
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt char DateBuf[50];
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt char TimeBuf[50];
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt /* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt REQUIRE(len > 0);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt if (FileTimeToSystemTime(&t->absolute, &st)) {
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd",
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt DateBuf, 50);
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt GetTimeFormat(LOCALE_NEUTRAL,
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt &st, "hh':'mm':'ss", TimeBuf, 50);
8a6f41d86ac80fd1397ffee65bed5131129a84e2Mark Andrews snprintf(buf, len, "%sT%sZ", DateBuf, TimeBuf);
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt } else {
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt buf[0] = 0;
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt }
aeff7de836558fa8002ab5db35292d2bb6450da8Evan Hunt}
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
bb5d14d7243d71e03d262ff175b355b52873e195Evan Huntvoid
bb5d14d7243d71e03d262ff175b355b52873e195Evan Huntisc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt SYSTEMTIME st;
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt char DateBuf[50];
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt char TimeBuf[50];
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt /* strtime() format: "%Y-%m-%dT%H:%M:%S.SSSZ" */
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt REQUIRE(len > 0);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt if (FileTimeToSystemTime(&t->absolute, &st)) {
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd",
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt DateBuf, 50);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt GetTimeFormat(LOCALE_NEUTRAL,
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt &st, "hh':'mm':'ss", TimeBuf, 50);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt snprintf(buf, len, "%sT%s.%03uZ", DateBuf, TimeBuf,
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt st.wMilliseconds);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt } else {
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt buf[0] = 0;
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt }
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt}