I have a web app that was created in PHP many years ago, and wanted to switch over to use Javascript and MongoDB as it's easier to scale the DB for changes over time. The dates and times are killing me, though. I've spent so much time trying to understand how it all works, and I feel like maybe I'm making things too complicated.
I have an office that is in the Eastern Time Zone. All my appointment times are set times, and the zone does not change ever. All my clients live in this time zone, and they would be scheduling by selecting an appointment time by clicking on a button associated with that time.
What do I need to do to:
save the appointment date and time to Mongo from ionic AND
display the retrieved appointment date and time from Mongo in the same time zone
I am even totally willing to just IGNORE time zone, if that is an option because I don't even care about the time zone. Daylight savings doesn't matter, because it will always be 8AM on whatever day. The time zone changing does not change the hour of the appointment.
Please help me with the most dumbed down version you have. With or without moment.js (I've tried both and keep failing miserably).
Mongo's officials documentation suggests saving timezone along with date information. Something like:
var now = new Date();
db.data.save( { date: now, offset: now.getTimezoneOffset() } );
Then you can reconstruct the original local time by applying the saved offset before you show the value:
var record = db.data.findOne();
var localNow = new Date( record.date.getTime() -
( record.offset * 60000 ) );
Related
I am trying to check if the date of the last time an element was clicked is equal to the current date. The current date is being created by the server and is 5 hours ahead of my local time, so at a certain time of day, the code stops working correctly because the program thinks it's now the next day.
Here is the code that is causing issues on my server side:
let todaysDate = new Date().toString().split(' ').splice(0, 4).join(' ')
let todaysDateMs = new Date(todaysDate + ', 00:00:00').getTime()
Promise.all([
Habits.updateMany({}, {
$set: {
todaysDate,
todaysDateMs
}
}),
Habits.updateMany({ lastClicked: { $ne: todaysDate } }, {
$set: {
clicked: 'false'
}
}),
The date that is being stored inside todaysDate is in UTC time and is 5 hours ahead. When it compares lastClicked (which is sent along with a PUT request from the client side in their local time) to todaysDate, it is setting clicked to false incorrectly because of the discrepancy between the timezones.
I am wondering if I can tell the server to create a date in the users local time or any way that I can work around this issue so that the two dates are the same. I don't want specific timestamps included, only the day, month and year.
Have you tried something like Moment.js? It makes dealing with things like this a lot easier. Check out their documentation or tutorals like this.
Generally, times on servers are done in UTC and only at the client is it converted to/from their time zone. This removes the need for the server to know anything about the client's time zone.
The client will need to send their time zone along with the lastClicked time. Then your server can read this time and adjust for time zone automatically. One example is to send the time in ISO 8601 format 2023-02-07T18:25:19-05:00 where the -05:00 indicates that this time is 5 hours behind UTC.
Alternatively, the client can pre-convert the timestamp their sending to UTC. JavaScript provides ways to do this, as do libraries such as Luxon.
Date values in MongoDB are stored as UTC time - always and only. You should never store date/time values as string, it's a design flaw.
I your case I suggest a 3rd party library like moment.js, Luxon or Day.js
They provide functions like DateTime.now().setZone('America/New_York').startOf('day').toJSDate();
With these functions it should be fairly easy to solve your requirements.
In my web application i have users select a certain time consisting of hours, minutes and a certain timezone.
The user selection is to trigger a function on my webserver at a certain time. But given that the user may select 11:00 in timezone "Europe/London", i need to account for the time difference between the time on my webserver and the triggering time and timezone selected by the user somehow, and calculate what the UTC version of the user selection would be.
The actual date is not important to me in this project, only that the triggering hour and minute needs to be adjusted so that a timed trigger function on my webserver matches the actual selection of time that the user has selected.
Any tips on how to achieve this using momentjs would be a great help ?
You can use moment.utc to convert all dates to UTC and then use date1.diff(date2, "hours") to get the diff in hours (or use minutes, seconds for more accuracy)
I am trying to create a scheduling application. The front end\UI is developed using JavaScript. The back end is a ASP.NET Web Api application which uses MSSQL server as the database. From the UI, user will schedule a job which can run daily/weekly/monthly. Each job can run for maximum of 3 months. The job will run on the server side at the specified time.
Assume user come and selects a job which will run for a week (From 23-Nov to 29-Nov) at 10 AM local time. In this case, I will make seven entries in the database starting from 23 nov (One for each day). Each row will have Start time, Start Date and some status related columns.
I have following querstions:
How do I store time information (10 AM in this case)on SQL server?
Should I get the time using JavaScript on client machine and then convert the same to UTC?
Should I get the time using JavaScript and also save the user time zone information?
What happens when DST related changes take effect?
Will library like momemnt.js will help in this scenario?
I am thinking of saving user timezone information and the saving his local time on the server.
Warning - Scheduling properly is hard. There's a lot more to consider. Please read this and this. Most of your questions are addressed there (though from the perspective of other languages, the challenges are the same).
You might also take a look at Quartz.net, which is sufficient for many scenarios.
To answer your specific questions:
How do I store time information (10 AM in this case) on SQL server?
For the recurrence rule, store the local time of the event. SQL Server has a time type, which works well for storing the time of day. You will need other fields for tracking the time zone, the start date, days of the week, and other pattern information.
For the specific instance that is scheduled to run, you calculate the UTC datetime based on all the information in the recurrence rule. At minimum, you schedule the next occurrence, and recalculate after each run. In some cases, you may decide to project the next N occurrences, depending on what you need to show to the users. (You could also use a datetimeoffset for this purpose. See datetime vs datetimeoffset.)
Should I get the time using JavaScript on client machine and then convert the same to UTC?
Should I get the time using JavaScript and also save the user time zone information?
To answer both questions: For scheduling, you should not discard the original input, which will be in the local time zone of the event being scheduled. That may or may not match the time zone of the user. You will need to ask the user to select the time zone of the event.
What happens when DST related changes take effect?
That's up to you. You will need to test this thoroughly. In general, there is a period of local time that is skipped, and a period of local time that is repeated.
When it is skipped, you have to decide when to run the event. Options include: 1) before the skipped time, 2) after the skipped time, and 3) not at all. In most cases, the preferred option is to run after the skipped time, by advancing the local time by the DST bias (usually 1 hour). For example, a daily event scheduled to run at 2:30 every day in Pacific time would run at 3:30 on the day of the spring-forward transition.
When it is repeated, you have to decide when to run the event. Options include: 1) at the first occurrence, 2) at the second occurrence, and 3) at both occurrences. In most cases, the preferred option is to run at the first occurrence only. For example, a daily event scheduled to run at 1:30 every day in Pacific time would run at 1:30 PDT, and not at 1:30 PST.
Exceptions to this include dealing with businesses that are open late into the evening and choose to stay open for the repeated hour. For example, a bar, restaurant, or movie theater. It is highly dependent on the specific use case and the choices made by the specific business.
Will library like moment.js will help in this scenario?
Not from a scheduling perspective, no. It can help with parsing, formatting, and validating input though. You might also use moment-timezone to help with selecting the event's time zone. If you were running this with node.js on the back end, then perhaps there would be more benefit.
The biggest challenge is actually one you have not talked about, which is maintaining the time zone data on your server. In your C# code, I recommend using Noda Time for this, instead of TimeZoneInfo. You can then update the tzdb data yourself as needed. You also need to think about the workflow of rescheduling the UTC instants of each occurrence, in the case that a time zone has changed its offset or daylight saving time dates.
I am creating an application where I have a pretty big set of dates and times, and I need to display these in the user's local time and date. All set dates and times are in BST; so for example 08-24-2014 16:00 BST = 08-24-2014 11:00 EST. Now, before coming here I spent good 3-4 hours looking for an answer but if anything, I got more confused. Is there any way, to convert a set of BST dates and times to the user's local settings automatically without them setting the time zone etc?
p.s.: I have two ideas in mind but I don't know if they would work nor how to execute them.
1) Get and change the BST date and time and convert it to a unit of measurement; get and change the user's local date and time and covert it to the same unit of measurement as above, calculate the difference in the new measurement, and convert that to the user's local time.
2) Use GeoLocation to find the user's date and time/ time zone and; convert the BST to whatever the GeoLocation spits out.
you can get the users machine timezone in javascript:
var currentDate = new Date();
var currentTimeZoneOffsetInHours = currentDate.getTimezoneOffset() / 60;
see documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
having the offset you can add it to your values
there is a javascript library Moment.js which allows you to query daylight saving values for specific dates and timezones.
because all your dates are in british summer time. first query if a date is in british winter time with isDSTShifted(). and subtract() an hour.
convert the date to another timezone
I have a user select a timezone. I then need to get the timezone that they have selected and have it passed through a search not the timezone the computer is using.
I know that:
.getTimezoneOffset //returns the computers offset
I need to get the timezone that the user has chosen as his or her timezone and pass it through the search.
My code looks like this
var expireFrom = $('input[name=expireFrom]').datepicker('getDate');
var expireDate = new Date();
if(expireFrom!=null)
expireFrom=expireDate.getTimezoneOffset();
How do I call the users chosen timezone and not the computers?
The Javascript Date object is not capable of working with other time zones directly.
Time Zone != Offset
Date pickers don't typically have time zone selection. If you have one that does, you need to tell what you're using.
If you really want to let your users pick a time zone, you'll need a control like this one.
To do anything useful with time zones, you'll need a TZDB implementation. You are best doing this in your back-end server-side code. If you must do it in JavaScript, you can try one of the libraries mentioned in this answer.