How the .getTime() can preserve the original date dd/MM/yyyy? - javascript

I have a trouble. I have an angular Javascript application that is storing the dates in mysql with milliseconds, but in some moments the date is interpreted with one more or less day. For example:
If the user selects in the date picker: 03/02/2017, the application is saving this (in milliseconds) as 02/02/2017 or 04/02/2017. I believe it is due to the timezone. This is the way I'm using to convert the date in milliseconds:
var temp = $("#datetimeField").val().split("/");
var newDatetime = new Date(temp[2], temp[1] - 1, temp[0]).getTime();
As you can see, I know the day, the month and the year before store it in the database. Normally the date is stored and works well, but in some moment the date changes as I showed above. How can I always get temp[2]/temp[1]-1/temp[0] ??? from the stored milliseconds?

Related

UTC displaying wrong times using moment.js [duplicate]

This question already has an answer here:
Why moment.js treats dash differently from slash?
(1 answer)
Closed last month.
I am trying to save a date and time for different time zones. I have changed my time zone in my chrome dev tools for testing purposes as follows
So for testing, I am trying to save a date time for London as '2023/04/21 23:55' when I save this datetimeoffset into my DB it gets stored as '2023-01-30T23:55:00+02:00'
but now when I try to read the format the date is as follows
var test = Moment(date); //'2023-01-30T23:55:00+02:00'
test = test.utc(true);
var format = "yyyy/MM/DD HH:mm";
return test.format(format);
it returns the date 2023/01/30 21:55. Why is it removing the 2 hours?
The issue is that your datetimeoffset has a timezone associated with it (+02:00). The 2023-01-30T23:55 part of your timestamp is not UTC time, it is local time, and the +02:00 signifies the offset of that timezone.
I'm not sure how you're saving that time in the first place, you probably forgot to specify the timezone as UTC. For example, if the date was created with Moment('2023-01-30T23:55:00'), then it that time will be intepreted as 23:55:00 on 2023-01-30 in the system's timezone, not UTC. To fix this, you need to use the Moment.utc('2023-01-30T23:55:00').

Inconsistency when converting DateTime to JavaScript

I have a ASP.NET webapi with a DateTimeZoneHandling set to Local and I am getting two different results when converting to a JavaScript date.
Example 1
Date returned from server 1932-10-13T00:00:00-04:00
var strDate = new Date("1932-10-13T00:00:00-04:00");
strDate.toISOString(); // 1932-10-13T04:00:00.000Z
strDate.toLocaleString(); // 10/12/1932, 11:00:00 PM
Example 2
Date returned from server 2013-05-09T00:00:00-04:00
var strDate = new Date("2013-05-09T00:00:00-04:00");
strDate.toISOString(); // 2013-05-09T04:00:00.000Z
strDate.toLocaleString(); // 5/9/2013, 12:00:00 AM
I expected behaviour should always be midnight as the dates returned from the server are always midnight. It appears all recent dates parse correctly, however, dates far in the past are incorrect.
The timezone can vary in some locales, for example, I'm UTC-0300, and on certain season shifts it becomes UTC-0200, so it indicates that your locale changed the offset too, making it display the time one hour lesser, basicaly because you locale adopted a different offset along the year.
The example bellow, I've changed your first example to use the same day and month than the second one, so that it proves you that old dates has nothing to do with it.
console.log("Example One");
var strDate = new Date("1932-05-09T00:00:00-04:00");
console.log(strDate.toISOString());
console.log(strDate.toLocaleString());
console.log("--------------------------");
console.log("Example Two");
var strDate2 = new Date("2013-05-09T00:00:00-04:00");
console.log(strDate2.toISOString());
console.log(strDate2.toLocaleString());
Further explanation on UTC/Zulu time
It has normalized the iso date to a zulu date (zero offset iso date). It is still the same datetime, but it has converted the timezone offset into hours making the timezone offset zero.
date [2013-05-09]
separator [T]
time [00:00:00]
offset [-04:00]
The fundamental aspect is that 00:00:00.000-04:00 is the same than 04:00:00.000Z.
If you're simply trying to display the date as someone living in that time would have remembered it (in your case, October 13th happened on October 13th), you may be able to (ab)use Moment Timezone, which appears to format the date as expected:
moment.tz("1932-10-13T00:00:00-04:00", "America/Toronto").tz("UTC").format(); // 1932-10-13T04:00:00Z
In your case, this hacktechnique results in 1932-10-13T04:00:00Z which may be what you are looking for.

How to save correct time in database?

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.

parsing a UTC ISO date to a local time date in javascript/jquery

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.

CouchDB filtering UTC dates by month and year

I save a UTC timestamp for every document in one of my Couch databases.
I want to query and filter those documents based on a specific month of a year. For this purpose I created a view with the following map function:
function(doc) {
var date = new Date(doc.activity.date);
emit([doc.user, date.getUTCMonth(), date.getUTCFullYear()], doc.activity.distance);
}
I query this view with for example: ?key=["1edd367d08770ea34586dbe6dc03ea2c",3,2013], which works perfectly fine as long as the UTC and local time is in the same month.
What I am asking is how can I ensure that a query like this returns all documents of a month, where the month is defined by the clients local time and not UTC?
The client is a JavaScript based Web-Client, but the query is handled through a NodeJS API in the back end.
What I am asking is how can I ensure that a query like this returns all documents of a month, where the month is defined by the clients local time and not UTC?
Find the start of the client's month and the start of the client's next month. These will form the range to query. For example:
var now = new Date();
var start = new Date(now.getFullYear(), now.getMonth(), 1);
var end = new Date(now.getFullYear(), now.getMonth() + 1, 1);
Then you will need to decide the best way to get this as UTC to pass to the database. For example:
var startUTC = start.toISOString();
var endUTC = end.toISOString();
(I am not sure of the specifics for CouchDB, so adjust if necessary.)
Then you need to do a range query in your database. You can't just match on year and month because your data is in UTC and the edges will not necessarily line up with your client's time zone.
I'm not familiar with Couch's syntax, but in SQL it would be something like this:
... WHERE activityDate >= startUTC AND activityDate < endUTC
Since we passed the start of the next month as the end date, make sure that perform an exclusive < and not an inclusive <= operation. Only the start date should be inclusive.
What I am asking is how can I ensure that a query like this returns
all documents of a month, where the month is defined by the clients
local time and not UTC?
If the client sends his local time, he must do so with a reference as to which timezone he is located in.
Otherwise, he must use UTC or GMT.
Without including the timezone, you would basically have to detect what timezone the client is located in and make assumptions which would not work out (e.g. a laptop located on a italian IP may be set with american time).
See: http://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators
The ISO 8601 format has time zone designator that would allow clients to send their localtime but with the attached time offset.
Couchdb supports this ISO 8601 format:
http://comments.gmane.org/gmane.comp.db.couchdb.user/14485
http://wiki.apache.org/couchdb/IsoFormattedDateAsDocId .
Remaining would be for you to do your conversions/comparisons etc to UTC/Unix time/ etc... whatever format works for you in order to be able to compare the KEY with the DATA.
The main point is that your comparing datetimes that are converted to the same timeoffset or UTC (no time offset).

Categories