I have a long int variable wich containes seconds since Jan. 1, 1970 in this format:
long int seconds = 1231241242144214;
i need to convert this seconds to double precision floating-point value. The integer part of the value is the number of days since midnight, 30 December 1899.
The fractional part of the value represents time. .5 is equal to 12:00 PM.
how can i convert?
There are 86400 seconds in a day, and 25569 days between these epochs. So the answer is:
double DelphiDateTime = (UnixTime / 86400.0) + 25569;
You really do need to store the Unix time in an integer variable though.
Related
I want to load utc_time< days > variable with year, month, day.
I do not know how to cast the result 'x' from date::utc_seconds to utc_time< days > and in general how to cast e.g. utc_time< milliseconds > to utc_time< days >...
auto x = to_utc_time(sys_days(year_month_day{ year{y}, month(m), day(d) }));
utc_time<days> utc_tp = ?x?; // now x => date::utc_seconds
Solved:
utc_time< days > utc_tp = time_point_cast< days >(x);
time_point_cast casts from fine precision time_point to a coarser precision time_point.
In addition to time_point_cast<days>, which truncates towards the epoch, there is also available:
floor<days>(x) : truncate to the beginning of the current day.
ceil<days>(x) : truncate to the beginning of the next day.
round<days>(x) : truncate to the closest day boundary.
time_point_cast<days>(x) is equivalent to floor<days>(x) when x is after the 1970-01-01 epoch, and equivalent to ceil<days>(x) when x is prior to the 1970-01-01 epoch.
I am seeing pretty weird issue. Somehow with my below code, I am seeing negative number getting printed out as shown below in my holder variable. I am not sure why it is happening.
-2147483648 days -2147483648 hours -2147483648 minutes ago
Here is my timestamp (current_unix_timestamp) value 1437943320 which is getting passed to my below method and then afterwards holder value is coming as shown above everything as negative.
char holder[100];
get_timestamp_value(current_unix_timestamp, holder);
inline void get_timestamp_value(long sec_since_epoch_time, char* holder) {
uint64_t timestamp = current_timestamp();
double delta = timestamp/1000000 - sec_since_epoch_time;
int days = floor(delta/60/60/24);
int hours = floor((delta - days * 60 * 60 * 24)/60/60);
int minutes = floor((delta - days * 60 * 60 * 24 - hours * 60 * 60)/60);
holder[0] = 0;
if (days) sprintf(holder, "%d days ", days);
if (hours) sprintf(holder, "%s%d hours ", holder, hours);
sprintf(holder, "%s%d minutes ago", holder, minutes);
std::cout<< "Timestamp: " << timestamp << ", sec_since_epoch_time: " << sec_since_epoch_time << ", Delta:" << delta << ", Days: " << days << ", hours: " << hours << ", mins: " << mins << std::endl;
}
// get current system time in microseconds since epoch
inline uint64_t current_timestamp()
{
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
}
Now this is what got printed out from the above cout logs:
Timestamp: 433430278724, sec_since_epoch_time: 1437943320, Delta:1.84467e+19, Days: -2147483648, hours: -2147483648, mins: -2147483648
Timestamp: 433679536303, sec_since_epoch_time: 1437943380, Delta:1.84467e+19, Days: -2147483648, hours: -2147483648, mins: -2147483648
Timestamp: 433929683258, sec_since_epoch_time: 1437943440, Delta:1.84467e+19, Days: -2147483648, hours: -2147483648, mins: -2147483648
Timestamp: 434179628271, sec_since_epoch_time: 1437943500, Delta:1.84467e+19, Days: -2147483648, hours: -2147483648, mins: -2147483648
Is there anything wrong happening in the above code which is causing this issue? Any suggestions will be of great help.
You should try to avoid doing arithmetic with a mixture of signed and unsigned integer types. The results are often surprising.
Clearly, timestamp is not the value you expect it to be, since timestamp/1000000 is 433430, which is considerably less than sec_since_epoch_time. Consequently, you might expect timestamp/1000000 - sec_since_epoch_time to be a negative number, but (surprisingly, as above), it will be a large positive number because the signed long sec_since_epoch_time is converted to an unsigned long prior to the subtraction, following the rules for the usual arithmetic conversions. The subtraction is then done using unsigned arithmetic, so the result is a positive number slightly less than 264, as seen by the value of delta.
Dividing that large number by 86400 is not sufficient to bring it into the range of an int, so the assignment
int days = floor(delta/60/60/24);
will overflow with undefined consequences (in this case, setting days to -231.)
To me, it seems a bit odd to ask for a duration in microseconds and then divide it by a million. Why not just ask for a duration in seconds?
But the underlying problem is that you are comparing the value returned by current_timestamp, which is the number of microseconds since the epoch of std::chrono::steady_clock, with the argument sec_since_epoch_time. It looks to me like sec_since_epoch_time is the number of seconds since the Unix epoch (Jan. 1, 1970). However, there is no guarantee that the epoch for a std::chrono clock has that value. (Apparently, on Linux, the epoch for std::chrono:system_clock is the system epoch, but I repeat that there is no guarantee.)
You cannot compare two "seconds since epoch" values unless they are seconds since the same epoch. Which means that the only way your code can work is if the clock which was originally used to get the value of sec_since_epoch_time is the same clock as you are using in current_timestamp.
In addition to ensuring that timestamp actually has the expected value, you should change timestamp to an int64_t (or cast it to int64_t for the purposes of the computation of delta).
I'm trying to create a program that takes the difference of two military times and get its time difference.
Example:
**AM to PM**
Time 1: 0900
Time 2: 1730
Time Difference: 8 hours 30 minutes
**PM to AM**
Time 1: 1200
Time 2: 1100
Time Difference: 23 hours 0 minutes
Using a couple of if than else statements, I was able to figure out how to convert from military hours into standard hours but I'm stuck with how to go about subtracting time. I was trying to come up with a way to do with on paper just with addition and subtraction but I haven't developed a method that works in all cases. Any help?
One option might be to split the time into two elements, the hours and the minutes.
First, take the time, ie. 1730 and divide by 100. If its an integer or similar, it should result in 17 hours (it will automatically round down).
Then take 1730 and mod it by 100 to get 30 minutes.
int time1 = 900;
int time2 = 1730;
int diffHours = time2 / 100 - time1 / 100;
int diffMinutes = time2 % 100 - time1 % 100;
If you're unfamiliar with modulus (%), it just returns the remainder after dividing the two numbers, so 7 % 3 would be 1.
Assuming your military times are stored as int values in the range 0000..2400, then the following function will return the difference between two such values.
#include <cassert>
extern int timediff_minutes(int t1, int t2);
int timediff_minutes(int t1, int t2)
{
assert(t1 >= 0 && t1 <= 2400);
assert(t2 >= 0 && t2 <= 2400);
assert(t1 % 100 < 60 && t2 % 100 < 60);
int t1_mins = (t1 / 100) * 60 + (t1 % 100);
int t2_mins = (t2 / 100) * 60 + (t2 % 100);
return(t2_mins - t1_mins);
}
Note that 2400 is useful for representing the end of the day — and using 2400 is sanctioned by ISO 8601:2004 Data elements and interchange formats — Information interchange — Representation of dates and times.
4.2.3 Midnight
The complete representations in basic and extended format for midnight, in accordance with 4.2.2, shall be
expressed in either of the two following ways:
Basic format Extended format
a) 000000 00:00:00 (the beginning of a calendar day)
b) 240000 24:00:00 (the end of a calendar day)
The representations may have reduced accuracy in accordance with 4.2.2.3 or may be designated as a time
expression in accordance with 4.2.2.5. To represent midnight the representations may be expanded with a
decimal fraction containing only zeros in accordance with 4.2.2.4.
NOTE 1 Midnight will normally be represented as [00:00] or [24:00].
NOTE 2 The end of one calendar day [24:00] coincides with [00:00] at the start of the next calendar day, e.g. [24:00] on
12 April 1985 is the same as [00:00] on 13 April 1985. If there is no association with a date or a time interval both a) and b)
represent the same local time in the 24-hour timekeeping system.
NOTE 3 The choice of representation a) or b) will depend upon any association with a date, or a time interval.
Representations where [hh] has the value [24] are only preferred to represent the end of a time interval in accordance with
4.4 or recurring time interval in accordance with 4.5.
I am looking in to the code about getting utc time.
static const long long SECSEPOCHS = 11644473600ll;
static const long long SECSto100nanosecs = 10000000ll;
static const long long MSECSto100nanosecs = 10000ll;
longlong mytime;
struct timeb now;
ftime(&now);
mytime = now.time;
mytime += SECSEPOCHS
mytime *= SECSto100nanosecs;
mytime += now.millitm * MSECSto100nanosecs;
I have following questions about above code.
What is the magic number "11644473600ll", how we got that number, and why we are adding this number to now.time that is returned by ftime. What is epcoh mean here?
Thanks
Epoch refers to the reference time that is used to calculate further events. For example if I decide that 1st Jan 2000 is the reference time (EPOCH) so whenever we I say "1 year past". It will mean that it is 1st Jan 2001 as our reference was year 2000.
Windows NT time is specified as the number of 100 nanosecond intervals since January 1, 1601. UNIX time is specified as the number of seconds since January 1, 1970. There are 134,774 days (or 11,644,473,600 seconds) between these dates.
The epoch is Midnight UTC, Jan 1 1970, the base for unixtime. The magic number is used to convert in between unixtime and microsoft's filetime which starts at Midnight UTC, Jan 1 1601.
Your code does the following:
ftime(&now);
mytime = now.time; // Get unixtime right now
mytime += SECSEPOCHS; // Adjust to seconds since microsoft's 1601 epoch
mytime *= SECSto100nanosecs; // Convert to 100-nanosecond units
mytime += now.millitm * MSECSto100nanosecs; // Add the millisecond part of the unixtime
The result is a value which is suitable for MS's FILETIME structure.
ftime returns Unix time, which is counted in seconds since 1 January 1970 00:00:00 UTC. The rest of the code converts it to a Windows NT file time, which is counted in units of 100 nanoseconds since 1 January 1601 00:00:00 UTC. The "epoch" is the "start of time", and 11644473600 is the Unix epoch expressed in seconds since the NT filetime epoch.
I am receiving from a data provider timestamps that follow this specification:
number of 100 nanoseconds since 1601
I am using boost::posix_time::ptime and I would like to convert the timestamps to posix time. Is there a simple way to do that ?
When did the switch from the Julian to Gregorian calendar occur for this system? Some countries switched before 1st January 1601; others didn't switch until much later. This will critically affect your calculation - by 11 days or so.
Since there are 107 units of 100 ns each in one second, you divide the starting number by 107 to produce the number of seconds since the reference time (the remainder is the fraction of a second). You then divide that by 86400 to give the number of days (the remainder is the time of day). Then you can compute the date from the number of days.
Since POSIX time uses 1970-01-01 00:00:00 as the reference, you may simply need to compute the correct number of seconds between 1601-01-01 00:00:00 and the POSIX epoch (as it is known), and subtract that number from the number of seconds you calculated.
number of 100 nanoseconds since 1601
It is Windows FILETIME value.
Boost.DateTime actually use Windows FILETIME for Windows platform.
Below is the relevant Boost source code that convert FILETIME to boost::posix_time::ptime:
(from boost/date_time/microsec_time_clock.hpp)
static time_type create_time(time_converter converter)
{
winapi::file_time ft;
winapi::get_system_time_as_file_time(ft);
uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
// and cannot be before 1970-Jan-01
std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
// microseconds -- static casts supress warnings
boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
std::tm curr;
std::tm* curr_ptr = converter(&t, &curr);
date_type d(curr_ptr->tm_year + 1900,
curr_ptr->tm_mon + 1,
curr_ptr->tm_mday);
//The following line will adjust the fractional second tick in terms
//of the current time system. For example, if the time system
//doesn't support fractional seconds then res_adjust returns 0
//and all the fractional seconds return 0.
int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
time_duration_type td(curr_ptr->tm_hour,
curr_ptr->tm_min,
curr_ptr->tm_sec,
sub_sec * adjust);
return time_type(d,td);
}
You can browse your Boost installation for the detailed implementation.