This question already has answers here:
When is it ok to store datetimes as local time rathen than UTC?
(1 answer)
How to store repeating dates keeping in mind Daylight Savings Time
(1 answer)
Managing timezone & DST issue for javascript application
(1 answer)
java Calendar, Date, and Time management for a multi-timezone application
(1 answer)
Closed 3 years ago.
I have a scheduling application, with a calendar that I build from scratch.
As a lawyer, you should be able to configure your available times for booking, like below:
A lawyer's availabilities in Australia
:
1- 10/01/2020, from 07:00am to 08:am
...
Here's what I do :
1- Get the epoch number of the entered date in Javascript :
const dateFrom = new Date(firstOfJanSevenAm).getTime() // 1578600000000
// Fri Jan 10 2020 07:00:00 GMT+1100 (Australian Eastern Daylight Time)
const dateTo = new Date(firstOfJanEightAm).getTime() // 1578603600000
// Fri Jan 10 2020 08:00:00 GMT+1100 (Australian Eastern Daylight Time)
2- Send this to NodeJS server and save it MongoDB
Mongoose.save({
from:dateFrom, //1578600000000
from:dateTo //1578603600000
})
3- Represent it inside the Calendar :
<div>{format(from, 'HH:mm')}</div>
Everything is working as expected.
Now, this lawyer is traveling to the US and he's in a coffee shop using the US local time ( any city), he opens the Calendar, he wants to add some availability, but in Sydney time. I need to provide him with a timezone dropdown so he can tell me that he wants the new date to be based on his home, Syndey.
Question :
1- Do I save the date as I'm doing ( as a number ), and save the timeZone separately next to it, and when representing it, just apply the timeZone?
Mongoose.save({
from:dateFrom, //1578600000000
from:dateFrom //1578603600000
currentTimeZone : 'America/Costa_Rica',
desiredTimeZone: 'Australia/Sydney'
})
<div>{formatWithTimeZone(from, 'HH:mm',desiredTimeZone)}</div>
Is this all I have to do? Or am I naively missing something that is going to trip me down the road?
And back to my original questions, where do I do the whole "always store time as UTC" thing?
All I've realized is, when I use the library that I'm using date-fns-tz and try to convert the user entered date to UTC, I get exactly the same output :
const dateFrom = new Date(firstOfJanSevenAm).getTime() // 1578600000000
const dateFromUTC = zonedTimeToUtc(dateFrom,currentTimeZone) // 1578600000000
// currentTimeZone is America/Costa_Rica, when he is in Costa Rica's caffee shop.
enter code here
1578600000000 === 1578600000000 = true
So why do I get the same output when converting the entered date, to it's UTC date?
I am going to give you an answer decoupled from the technical implementation.
Let's think by contradiction, you have a lawyer living in Australia and another living in Switzerland, what happens if you decide to store time in their preferred location?
You then need to save two information: the time of course (11 am) but it's relative so you also need to store the timezone (11 am in Australia) or (1 pm in Switzerland)
Now what happens if your lawyer travels to France? Do you want to update all his calendar information? 11 am is not 11 am anymore.
UTC solves this problem, you just need to store 11 am or 1 pm. UTC is arbitrary absolute, universal by convention.
So your backend/database should store this kind of information in UTC, always. And you need a way to know your user's timezone, maybe it's possible to update it using a web interface and it could be stored in a user database or just cookies. Maybe you want to derive it yourself by using your user's location, IP, browser's language, whatever.
Now that you know his timezone, your server can send UTC (absolute) time to the client and the client can seamlessly display the correct (relative) time.
The client deals with relative time, the server always makes it absolute.
So why do I get the same output when converting the entered date, to it's utc date?
The value returned by getTime is the number of milliseconds since 1 January 1970 00:00:00 according to universal time.
Therefore, UTC and getTime both represent a moment in time using the same universal timezone.
Do I save the date as I'm doing, and save the timeZone separately next to it, and when representing it, just apply the timeZone?
Don't save the timezone with the date. Just save the date in universal time. If you need to save timezone. That should go in user settings. However, you can guess the timezone; therefore, you don't need to save this information.
Saving the date
When you do save the date to the database, it should be represented by a UTC time string or by a UNIX timestamp, both options demonstrated below.
UNIX timestamp
UNIX timestamp should be in seconds. getTime returns milliseconds. You can just divide by 1000 to get the UNIX timestamp.
const unixTimestamp = new Date('December 17, 1995 03:24:00').getTime() / 1000;
UTC Date string
const utcDate = new Date('December 17, 1995 03:24:00').toUTCString();
Displaying the date
When you get the date from the back-end, then, converted it to the correct timezone.
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
const fromUnix = utcToZonedTime(1578423483, timezone)
const fromUtc = utcToZonedTime('Fri, 02 Feb 1996 03:04:05 GMT', timezone)
Closing thoughts
Dealing with timezones can be confusing. I am not to familiar with date-fns-tz. If you have the option, I would suggest migrating to Moment.js. Moment.js is the de facto standard JavaScript library these days - I highly recommend it.
I have a range of cells which contain dates in the following format:
7/27/2018 17:03:46
When I use:
var range = spreadsheet.getRange(1, 1, 20).getValues();
Logger.log(range[1][0]);
I get
Sat Jul 28 02:03:46 GMT+02:00 2018
instead of
7/27/2018 17:03:46
How do I get the correct value?
My Timezone is GMT +02:00
I've tried using new Date().
The link below will take you to the Spreadsheet:
https://docs.google.com/spreadsheets/d/1H7MAEfr0QbFuNwA8N_bm-08f_Phs8G2NNOQDYG-IA4E/edit?usp=sharing
Resolved
The problem was the origin of the data. I was copying and pasting the table values from an Excel Spreadsheet which is a log from a Chinese machine which as a different time zone. When I copied and paste from Excel to Google Sheets it changes the timezone of Google Sheets :l
I'm getting a 60-minute offset and I'm not sure why.
When I create a date, I get the following date:
Tue Feb 27 2018 11:30:28 GMT+0100
When I retrieve it from the database, I get the following date:
2018-02-27T11:30:28.000Z
I then display if with the following line of code:
moment(this.props.starttime).format('LT')
And get this in my view:
12:30
But I can see the value of the moment object being the following:
2018-02-27T11:30:28.000Z
Apparently, I have a 60 minutes offset from UTC time.
What's going on here? Because when the user select 11:30 in this case, it displays 12:30 in the view afterwards.
Edit 1: This is how I send the dates to my database
axios.post( `https://xxxxxx.ngrok.io/api/book?starttime=${moment(this.props.starttime).format()}`)
and this is how I save it in my database (Rails API)
def create
#request = Request.new(start_datetime: params[:starttime])
end
It looks like you're losing the offset from UTC somewhere between creating the date and saving it in your database, and that your server uses UTC while your client system uses UTC+0100.
Exactly how do you create the date and then save it so that you can retrieve it later?
I've added a script in google sheets that will send me a reminder depending some start date values.
I receive this nice email, but I only want to keep the date without time and time zone.
The campaign will start in 8 days (Fri Apr 24 2015 00:00:00 GMT+0300 (EEST)).
What should I do?
I'm not exactly sure how Google Spreadsheets work, but you can do:
new Date(my_date_string).toDateString();
to convert a date into something more readable.
You can try this:
ICC.Utils.formatCalendarDate = function (dateTime) {
return moment.utc(dateTime).format('LL');
};
I am using Facebook FQL to get photos and the time when they were created. The problem is am getting the created time as some long integer value e.g. 1306776492.
Now I am unable to convert it to proper date time using javascript.
Can anyone point me in the right direction
You can set a Date objects time with the setTime method.
var d = new Date();
d.setTime(1306776492*1000);
document.write(d);
returns
Mon May 30 2011 20:28:12 GMT+0300 (FLE
Daylight Time)
http://jsfiddle.net/niklasvh/ANRcm/
If you want the date to be printed in a different format, just have a look at the other methods available for Date()