Parse DateTime when given as a Number/Double - ruby

I am working with some date times from a piece of weather hardware which logs to a .dbf file. I can pull this up from the ruby script/web server I am using, but I get numbers such as
41836.532638889
I am unsure how the date time is represented so having a hard time of knowing how to parse it. I would preferably like to parse it in Ruby, so code would be a plus, but I could figure out how to do it if I knew how it was represented.

The date is an OLE Automation formatted date which is common in Excel. As Google says it is
An OLE Automation date is implemented as a floating-point number whose integral component is the number of days before or after midnight, 30 December 1899, and whose fractional component represents the time on that day divided by 24.
The corresponding Ruby code is
def self.convert_time(t)
Time.at((t - 25569) * 86400).utc
end
The subtraction shifts the time to the day unix time starts (1 January 1970). Unix time is in seconds so converting days to seconds: 24*60*60=86400. Converting to utc time for convenience.

Try Time.at(your_number/double). You can then format it as required.
Time.at(41836.532638889)
=> 1970-01-01 12:37:16 +0100

41836 - number of days passed from 12/31/1899 (zero-date), 532638889 - number of seconds passed from the midnight of the date mentioned.

Related

Convert Apple Cocoa Core Data timestamp in Excel

I'm trying to convert the Cocoa timestamps to human-readable dates with time. For context, these numbers are coming from the history.db file within ~/Library/ for Safari. I can convert individual numbers with the awesome tool at epochconverter.com, but they do not offer a batch converter for Cocoa.
As an example, 638490901.575263 should convert to Friday, March 26, 2021 3:35:01 PM GMT-07:00. In Excel, I'm using:
=("cell reference"/86400000) + DATE(2001,1,1), but getting 1/8/01 9:21 AM. Looks like I need to add time for the Cocoa Epoch delta, but unsure how to do that.
Thanks for any help!
You have too many 0 in the formula, the number is the number of seconds since the start of 1/1/2001. There are 86400 seconds in a day. Then add the start date so we get the correct number of dates from 12/31/1899 which is what Excel uses. Then we need to subtract 7 hours to get the correct time zone difference.
=(A1/86400) + DATE(2001,1,1) - TIME(7,0,0)

Working with datetime in Elixir

I need to find a difference in minutes between the time from a database retrieved by Ecto and current time, in UTC. As far as I know, timing operating on Elixir aren't trivial without using third-party libraries such as Timex. I, however, want to avoid using third-party dependencies. So how can I find a time difference? I know I can get the current time by DateTime.utc_now(), but what's next, how to subtract a date-time from a database, which is in Ecto.DateTime format, from it?
I believe there are plans soon for Ecto to use the native Elixir Datetime format for the time being, I know your pain.
One solution is to convert the ecto date time to the erlang date time format:
{{YYYY, MM, DD}, {HH, MM, SS}}
And then compare that using the erlang calendar library. For example, say we had a Post model and we wanted to know how long ago it was updated:
Repo.Post.get!(%Post{}, 1).created_at
|> Ecto.DateTime.to_erl
|> :calendar.time_difference(:calendar.universal_time)
So let's say this post was created roughly 1 month ago (2016-10-25T10:24:23).
Running it through the above function would return:
{30, {17, 30, 53}}
Meaning 30 days, 17 hours, 30 minutes and 53 seconds ago.
You can easily from there destructure the tuple and take only the components you need (in your case the minutes).
E.g.
{_, {_h, minutes, _s}} = time_diff

Get given timezone timestamp

I am playing around with timezone and noticed something wierd.
I am currently in the BST timezone which is an hour ahead of GMT.
now := time.Now()
location, _ := time.LoadLocation("Atlantic/Cape_Verde")
timeAtZone := now.In(location)
fmt.Println(timeAtZone)
timestamp = timeAtZone.Unix()
fmt.Println(timestamp)
fmt.Println(now.Add(-time.Hour).UTC().Unix())
fmt.Println(now.UTC().Unix())
You will notice that the timestamp is that of BST my current timezone.
How do I get the timestamp of GMT???
http://play.golang.org/p/oq0IRYa0h7
Unix time is absolute. There is no "BST Unix time." There is no "Atlantic/Cape_Verde" Unix time." There is only Unix time. It is the number of seconds since a specific moment (00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, not counting leap seconds).
Time zones are related to the representation of time, not time itself. It is the same moment for you as it is for me, wherever we are in the world (leaving Einstein aside for the moment). We just happen to call that moment different things. Setting the location on a *Time just indicates how you would like to display the time. So if by "timestamp" you mean "string representing the time," you can get the UTC timestamp with time.Now().UTC().String().
Make sure you check your errors, I assume it's telling you there's an issue.
Have you checked: http://golang.org/pkg/time/#LoadLocation
Is your timezone in: $GOROOT/lib/time/zoneinfo.zip?
For me:
time.LoadLocation("CDT") // my time zone
time.LoadLocation("CST")
Both result in an error.
To get my time zone, I must do:
time.LoadLocation("America/Chicago")
Make sure f.Timezone is valid.

Python find what is the epoch time after xxxx milliseconds

I am writing a python script which mainly involves decoration of console output.
I have some value called expiration_time which is in milliseconds. When I display expiration_time on console it is hard to find how much time exactly left to expire. User needs to do some calculation to know how much time is left.
So I decided to print epoch time instead. I want to do something like this:
epoch_time_at_which_expiration_will_happen = current_epoch_time + expiration_time_in_milliseconds
I want to output epoch_time_at_which_expiration_will_happen. How can I do it?
Not really sure what you are trying to output, the time at which expiration happens or the time until the expiration?
Either way, I would use a datetime object instead of the epoch time and convert the milliseconds to microseconds. The datetime objects allow you to do the math you want and to display the output formatted nicely.
https://docs.python.org/2/library/datetime.html

Exporting to Excel - What to do with timestamps?

I've got Time objects that I'm writing to an Excel file. I'm using the axlsx library. The class that converts dates to the cell data is DateTimeConverter, which turns it into a float timestamp.
The times are displayed as mm/DD/YYYY HH:MM:SS as expected, but the values are in GMT time.
Is there a way to make Excel format the times for a particular time zone, or the reader's local timezone? My current solution is to export the formatted time as a string, and I am dissatisfied with this.
Is there a way to do this without adding a VBA macro? (Please note that I'm not trying to convert the local time to GMT with a VBA macro as per the linked "duplicate" question, but rather display the GMT time to a local time - preferably without a VBA macro, if possible.)
Short answer
Excel timestamps don't know anything about time zones. If you want to export a value and display it in local time, you need to add the utc_offset to the time before you send it to Axlsx.
t = ...
excel_time = Time.at(t.to_f + t.utc_offset)
sheet.add_row ["Time:", excel_time]
Long answer
In Ruby (and many other programming languages) timestamps are represented as the number of seconds since Jan 1, 1970 00:00:00 UTC (the epoch). The Ruby Time object also retains a time zone, so that when you print it out it can display the local time. If you change the time zone, the time will be printed out differently, but the underlying number stays the same.
In Excel, timestamps are represented as the number of days since Jan 1, 1900 (or 1904, depending on the workbook settings); time is indicated as a fractional part of a day. If today's date is 41262, then 12am is 41262.0 and noon is 41262.5. There are no time zones in this scheme, time is simply a number you read off your watch.
When Axlsx exports a Ruby Time object to Excel, it calls to_f to get the time value in seconds since the epoch, then does some math to convert that to the serial number that Excel likes. Great! But it threw away the utc_offset, which is why the times are appearing in Excel as UTC.
The solution is to simply add the UTC offset to the times in your code, before you hand them over to Axlsx. For example, if you are on Eastern Standard Time, you must subtract five hours. Technically, the new time object you are creating is incorrect as far as Ruby is concerned, but we're just doing this to please Excel.

Resources