سؤال

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top