I have a database field called CreatedDate which is a timestamp field and holds the date and time. It currently holds the GMT time.
At the moment this field is displayed as it is on the web pages.
We want to amend this to show date/time as per browser local time zone
Can you please let us know how we can do this.
Thanks in advance
If you can represent the universal time as a count of milliseconds since the 1 Jan 1970 epoch at the server then you can have the page code construct Date instances at the client using the client time zone, but starting from that UTC reference. It's the normal behavior of the Javascript Date() constructor:
var clientDate = new Date(serverUTC);
Now exactly how you get that UTC value depends on your server language. In a JSP page it'd be pretty simple:
var clientDate = new Date(<%= whatever.getTheDate().getTime() %>);
or
var clientDate = new Date(${something.theDate.time});
Once you've got the date value as a client-side Javascript Date instance, you can just update the field(s) with the string. There are no built-in Date formatting tools, but the old standard date.js might help with its ".toString()" formatter.
Related
This will be my first time working with time zones, I hear this is a major pain point for a lot of developers so I'm asking this question as a sanity check to make sure I'm not missing anything.
My use case is rather "simple", I want to have a date time picker where the user can choose their date and time in their local timezone (in other words what they see in the picker matches what their computer's date and time is set to).
Then I want to take this chosen date and time, convert it to UTC and send it to the server to be saved.
When the user goes to certain pages I take the UTC date/time coming back from the server and convert it to the user's local date/time and display it to them in a user friendly way.
Do I need a library like moment timezone for this or will the browser's native date methods like Intl.DateTimeFormat, new Date().getTimezoneOffset(), etc be enough? (I only need to support the latest modern browsers so I'm asking this from a "does it do what I need" ​point of view not a browser support POV).
It seems all I need are 2 things:
A way to get the user's timezone offset from UTC (so I can convert their local time to UTC to send to the server and also to convert UTC back to their local time to display it to them on certain pages)
A way get their timezone abbreviation (EST, PDT, CDT, etc) to show in the UI
Do I need a library for these? And if not why do people use such large libraries for working with timezones anyway?
You don't need a time zone library for the functionality you mentioned.
// Get a Date object from your date picker, or construct one
const d1 = new Date("2020-08-02T10:00");
// Convert it to a UTC-based ISO 8601 string for your back-end
const utcString = d1.toISOString();
// Later, you can create a new Date object from the UTC string
const d2 = new Date(utcString);
// And you can display it in local time
const s1 = d2.toString();
// Or you can be a bit more precise with output formatting if you like
const s2 = d2.toLocaleString(undefined, {timeZoneName: 'short'});
console.log("UTC: ", utcString);
console.log("Local Time (default string): ", s1);
console.log("Local Time (intl-based string): ", s2);
Keep in mind that not all time zones will have an abbreviation, so those ones will give output like "GMT+3".
I have one object called appointment which has two properties: StartDate and EndDate.
When I make POST request I send these values using ISOString time .
this.appointment.StartDate.toISOString()
On the server-side, I received these properties with correct values. Also, it seems to be correct when I create model in order to save appointment to the database. I used .ToUniversalTime() method.
var newAppointment = new Appointment()
{
StartDate =Convert.ToDateTime(model.StartDate).ToUniversalTime(),
EndDate = Convert.ToDateTime(model.EndDate).ToUniversalTime(),
SpecialityId = speciality.Id,
LocationId = location.Id,
PatientId = patient.Id,
UserId = user.Id,
Observations = model.Observations
};
But in database I found another values. Can explain somebody why is this behaviour ?
For instance, I used 2017.09.01 11:00 for StartDate and in database i found 2017-09-01 08:00
The server and database is located in the westeurope.
A few things:
Don't call ToUniversalTime in a web application. It's designed to convert from the server's local time zone to UTC. The server's time zone should be irrelavent to your application. Web applications should never use ToUniversalTime, ToLocalTime, DateTime.Now, TimeZoneInfo.Local, DateTimeKind.Local or any other method that uses the time zone of the computer it's running on.
Ideally, on the server side, your model.StartDate and model.EndDate would already be DateTime objects, because they'd have been deserialized that way. Therefore, you probably don't need to call Convert.ToDateTime. If they are strings, then I would adjust your model class accordingly.
On the client side, assuming StartDate and EndDate are JavaScript Date objects, and they were created using local time values (that is, the time zone of the browser), when you call toISOString, you're not just getting a string in ISO 8601 format - it is also converting it from the browser's time zone to UTC.
In your example, the UTC time is 3 hours ahead of UTC for the date and time shown. From your profile, I see you are located in Romania, which is indeed UTC+3 for this date, because it is currently observing Eastern European Summer Time. When Summer Time ends (on October 29, 2017 at 04:00), it will return to UTC+2. For this reason, you cannot simply add three hours to all values.
If you want to send local time values from the client, you should send them in ISO 8601 format, without any Z or offset, for example 2017-09-01T11:00. There are several ways to achieve this:
The best way is to not have them in a Date object to begin with. For example, if your input uses the <input type="datetime-local" /> input type (as specified in HTML5), the .value property is not a Date object, but rather a string in ISO 8601 format.
If you can't avoid a Date object, then create a local ISO string, like this:
function dateToLocalISOString(date) {
var offset = date.getTimezoneOffset();
var shifted = new Date(date - offset * 60 * 1000);
return shifted.toISOString().slice(0, -1);
}
OR, using Moment.js:
moment(yourDateObject).format("YYYY-MM-DD[T]HH:mm:ss.SSS")
Lastly, you will probably read advice from others about storing these as UTC. Don't listen. The advice "always use UTC" is shortsighted. Many scenarios require local time. Scheduling appointments is a primary use case for local time. However, if you need to act on that appointment, you'll use the current UTC time, and you'll also need some information about the time zone for the appointment so you can convert from UTC to the appointment's time zone. For example, if this is something like an in-person doctor's office appointment, then it's safe to assume the time zone of the doctor's office. But if it's an appointment for an online meeting, then you'll have to capture the user's time zone separately and apply it on the back end where appropriate.
The problem is with your current timezone.
What your application does is get current timezone (+3) in this case.
Now it got your timezone but it will convert to utc time. So what will happen, your current time will be -3 hours.
If you not adjust to summer and winter time then you can simply add 3 hours to the datetime. Otherwise you have to get the offset of your timezone and add that to the current datetime value.
Take care if you use this application in different timezones. For example You life in +3 and some else life in +2 timezone.
I put a UTC .NET/JSON date from .net on client side. When I run the following command:
moment(value.Planet.when).utc()
The returned date from webservice:
"/Date(1469271646000)/"
I get a date in the _d parameter showing the current accurate UTC date with GMT+0300 on right side.
I want to convert this time to local time on the user machine and what ever I do, I always get the time 3 hours back.
I do this:
moment(value.Planet.when).local().format('YYYY-MM-DD HH:mm:ss')
and I get the same date time as the UTC. I don't understand how can I get momentjs to show the UTC time relative to the local time. I checked that the momentjs object is indeed UTC.
I thought that if I pass the moment.utc() function the UTC date that I've got from the webservice (originally from the database), I can just run the local() function and I'll get the accurate hour relative to my area, but it didn't work.
You can use moment(date).format('YYYY-MM-DDTHH:mm:ss');
Eg:- if you date "/Date(1469271646000)/"
ip-> moment(1469271646000).format('YYYY-MM-DDTHH:mm:ss');
op-> "2016-07-23T16:30:46"
Do not use the _d property. It is for internal use only. See this answer, the user guide, or Maggie's blog post on the subject.
As far as you question of how to convert to local time, you don't actually need to convert at all. You're already parsing the input value in local mode, so you can just use it directly:
var m = moment("/Date(1469271646000)/"); // gives you a moment object in local mode.
var s = m.format(); // lets you format it as a string. Pass parameters if you like.
var d = m.toDate(); // gives you a Date object if you really need one
Try to avoid using Date objects unless they're required by some other controls or libraries you're using. Most operations can be done strictly on moment objects.
I have tried to search for the answer already, and although I find answers that are very similar, I don't think they are exactly what I am looking for. Please forgive me if this is already answered elsewhere.
I am trying to parse an ISO date in javascript so that I can compare it to the client system date and display information depending on if the ISO date is before or after the client system date.
This was fine until I needed to support IE8 and now I am stuck.
I have created a function because I have three different dates that I need to do this to.
for example, my ISO date is: 2015-12-22T11:59 in UTC time.
but once my date is parsed, the full date is 11:59 in local time, no matter which time zone i test, it's always 11.59 in THAT time zone.
I know that the function I have created currently doesn't do anything with timezone, this is where I am stuck. I don't know what to add to get my end date to change as a reflection of the timezone of the clients machine.
any help or advice would be greatly appreciated.
I am not able to use something like moments.js because I have an upload restriction.
Jquery is available though. or plain javascript.
<script>
function setSaleContent() {
//creating a new date object that takes the clients current system time. so we can compare it to the dates stored in our array
var currentDate = new Date();
console.log(currentDate + " this is the clients date ");
//These variables actually come from an external array object, but I'm putting them in here like this for this example.
var destinations = {
freedate: "2015-12-16T11:59",
courierdate: "2015-12-22T11:59",
nextdaydate: "2015-12-23T11:59",
}
//fetch all the ISO dates from the array.
var freeDateISO = destinations["freedate"];
var courierDateISO = destinations["courierdate"];
var nextdayDateISO = destinations["nextdaydate"];
//I am creating this reusable function to split up my ISO date for the sake of IE8.. and create it into a date format that can be compared against another date. I know that this isn't doing anything with my timezone and that is where my problem lies.
function parseDate(str) {
var parts = /^(\d{4}).(\d{2}).(\d{2}).(\d{2}):(\d{2})/.exec(str);
if (parts) {
return new Date(parts[1], parts[2] - 1, parts[3], parts[4], parts[5]);
}
return new Date();
}
//I would like this date to change to reflect the time zone of the clients system time.
//currently returns the date at 11.59 regardless of timezone.
//If i was in GMT i would want it to say 11.59
//If i was in CT time I would like this to say 05.59
//If i was in Perth I would like this to say 19:59
var freeDate = parseDate(freeDateISO);
console.log(freeDate + " this is the converted date for IE")
}
window.onload = setSaleContent;
The simple solution is to append Z to the ISO date to indicate it is in UTC time, such as 2015-12-22T11:59Z.
When JavaScript parses that date as a string, it will then automatically convert the UTC date to the local time zone.
While this is simple enough with a parsing call in the form new Date(str);, it will not play nice with your parse call with numerical arguments targeting IE8 and other old browsers.
A polyfill for parsing ISO dates with timezone exists: Javascript JSON Date parse in IE7/IE8 returns NaN
This can replace your custom parseDate function after some modification to take an input string.
Alternatively, implement your own custom date manipulater to account for the local timezone using the .getTimezoneOffset() method on the newly created date, which gives the time zone offset in minutes, but you will have to come up with a method of utilising the offset such as adjusting hours and minutes, due to the limited methods of the JavaScript date object.
I am having an issue with displaying the correct time. I have a php script that when a button is clicked it inserts the CURRENT_TIMESTAMP into the database. The server is located in Arizona, I am in PST. When I call the time in my script it shows Arizona time, but I need it to show the users time. So 2015-02-18 16:06:28 Arizona time, MY time is 2015-02-18 15:06:28.
How do i get the correct time. I am using moment.js, but no matter how i format it it shows the incorrect time. I am not sure but is DST, not being considered?
var time_in = time_in;//format 2015-02-18 16:17:33
var timeIn = moment.utc(time_in, "HH:mm a").format("HH:mm a");
Moment.js parses the date as a locale date-time. So when you do moment.utc(time_in), you're converting it to UTC according to your local time (PST), shifted forward or backwards.
So what you need to do is do a moment.fn.utcOffset. Arizona is UTC-07:00, so we would want to add +7 to the offset. You can do the same using moment.fn.zone but that's getting deprecated.
var utcTime = moment.utc('2015-02-18 16:06:28').utcOffset(+7).format('YYYY-MM-DD HH:mm:ss')
// returns "2015-02-18 23:06:28" which is the UTC time
Now you have the moment in UTC, you can convert it to the client localtime:
moment(moment.utc(utcTime).toDate()).format('YYYY-MM-DD HH:mm:ss')
// returns '2015-02-18 15:06:28' (which is PST)
moment.utc(utcTime).toDate() above just converts the utc time to your local time, then formatting it with momentjs
EDIT: If possible, you should use unix timestamp when sending to server, then you don't have to deal with UTC or timezones. You can convert to local time with moment.unix(unixTimestamp).format('YYYY-MM-DD HH:mm:ss')
It looks like you are using Javascript to get the time of the client, but then not passing that to the PHP. I'm not sure how your app is structured, but you could create an input tag with the type="hidden". Then using Javascript, find the element and set it's value to Date().
Here is an example: http://jsfiddle.net/43jfefuq/
Now when you submit this form with PHP, the value in the field will be the client's local time.