In casual testing, I can see these give different results:
//assemble from component parts Datetime now = System.now(); Date today = Date.newInstance(now.yearGmt(), now.monthGmt(), now.dayGmt()); //assemble from... something else!? Datetime now = System.now(); Date today = now.dateGmt();
I thought I understood that
Datehas no concept of timezone. The same day is the same day everywhere. So, what is the purpose of
dateGmtthen? What use cases would suit each of the above code samples?
For the intention of writing to a
Datefield type in the database, I want to get the “true GMT date” from a
Datetimeinstance. To do that, which technique is appropriate and why?
First, I need to correct your question. There is no
Date.DateGMT() function; the
Date class has no member
DateGMT. I believe you meant
DateTime: A value that indicates a particular day and time, such as a timestamp.
Date: A value that indicates a particular day. Unlike Datetime values, Date values contain no information about time.
The important concept here is that a DateTime represents an exact moment in time, which has different representations in each timezone. For example, as I type it is 11:56 AM on Feb 23 on my clock, as I am in the Eastern Standard timezone in the US. However, it is currently 12:56 AM on Feb 24 in Shanghai, China (China Standard Time). It is the same moment in time, but I’ve listed two representations of it, which have different Date portions. Another representation is GMT, which is 4:56 PM on Feb 23.
Apex’s DateTime object only exposes two representations of a moment in time: The date & time in time zone of the context user, and the date & time in GMT.
So to answer the question “What is the purpose of
DateTime.dateGmt() function?” – This function returns the Date component of the GMT representation of the exact moment in time represented by the DateTime. In contrast,
DateTime.date() returns the Date component of the context’s user’s timezone’s representation of the DateTime.
In a comment on another answer showing an example of
dateGMT() returning different answers, you said, “I thought dates were timezone independent”. The apex
Date object has no time component, and has no timezone component. This is important – a
Date object is just a month, day, and year, with no concept of time or timezone. Consider some examples:
- If I say “Let’s meet on May 1”, the actual moment in time depends on what time I mean, which I didn’t state.
- If I say “Let’s meet at 10 AM on May 1”, the actual moment in time depends on the timezone, which I didn’t state.
- If I say “Let’s meet in Sydney Australia at 10 AM AEDT on May 1”, we’ve pinned down an exact moment in time. The Date portion of the Local Time Zone (Australia Eastern Daylight Time) representation of that moment in time is May 1, 2015, but the Date portion of the GMT representation of that moment in time is Apr 30, 2015.
In your question, you provided two code samples:
//assemble from component parts Datetime now = System.now(); Date today = Date.newInstance(now.yearGmt(), now.monthGmt(), now.dayGmt()); //extracted from existing datetime Datetime now = System.now(); Date today = now.dateGmt();
There is no real difference here; both snippets will return the same Date value. That’s because
DateTime.yearGmt() is the same as
DateTime.monthGmt() is the same as
DatTime.DateGmt().month(), etc. Which method should you use? Doesn’t really matter, but the second one is shorter to read, more obvious in intent, and probably uses fewer cycles.
In your comment to another answer you asked, “I want to get the ‘true GMT date’ from a datetime instance… which technique is appropriate and why?” Either approach will give you the correct Date for the GMT representation of the moment in time in your DateTime. Just be sure that you are constructing the DateTime correctly. If you are using System.now(), no worries. but if you are using
Datetime.NewInstance(year, mo, day, hr, min, sec), keep in mind that the date and time values you provide will be treated as being in the context user’s timezone. If you mean to provide the date and time values as GMT, use