I want to convert 2018-02-21 15:47:35
UTC to epoch UTC form. How do we do it? I am currently in PST.
SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-DD HH:MM:SS");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
date = df.parse(dateString).getTime();
The code above should return the number of milliseconds since January 1, 1970, 00:00:00 GMT
, but I'm getting an incorrect value.
Your pattern must be
yyyy-MM-dd HH:mm:ss
, as the other answers told you:I just want to add some more details.
First of all, take a look at the patterns description in the javadoc: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Note that a lowercase y is not the same as the uppercase Y (lowercase is the year, while uppercase is the week year - 2 different fields with completely different definitions)
Also note that uppercase D is the day of the year, while the day of the month (which is what you want) is the lowercase d. And uppercase M is the month, while lowercase m is the minute of hour.
And uppercase S is the milliseconds field, while the seconds are represented by lowercase s.
And
SimpleDateFormat
's design doesn't help: the class simply tries to parse the string, even if the month field (MM) appears twice in your pattern, while the minutes field doesn't appear (and it's set to a default value of zero - all behind the scenes, without any warning, no indication of error at all).Conclusion: always read the docs :-)
For Java 8 or higher, consider using the new date API, which is much better because it doesn't have all these behind-the-scenes stuff:
This API will also throw an exception if you use a pattern like
YYYY-MM-DD HH:MM:SS
, because it will try to parse the minutes value 47 as a month (because uppercase MM will be in the respective position), and 47 is not a valid month.Also can be done via java8 time library:
The only problem with your code is DateFormat
please check. https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
I'm in PKT so output would differ...
Expected: 2018-02-21 15:47:35 UTC is equivalent to 1 519 228 055 000 milliseconds since the epoch of January 1, 1970 at 0:00 UTC.
Observed: Your code in the question gives 1 514 818 800 035. So it’s 4 409 254 965 milliseconds off, a little over 51 days.
The solution:
This gives the correct 1 519 228 055 000.
What went wrong?
One of the many troublesome traits of
SimpleDateFormat
is that with its default settings, if you specify an incorrect format pattern string, it will very often give you an incorrect result and pretend all is well. The modern Java date and time API that I am using in my snippet, is trying somewhat harder to figure out when the pattern doesn’t make sense and tell you it’s wrong somehow. As an example, let’s try your format pattern with the modernDateTimeFormatter
:This will throw a
java.time.format.DateTimeParseException: Text '2018-02-21 15:47:35' could not be parsed at index 14
. Index 14 is where 47 is in the string, it was supposed to be the minutes. Apparently 47 doesn’t matchMM
in the format. If you haven’t figured out yet, check the documentation. It says that uppercaseM
is for “month-of-year”. So what the formatter is trying to tell you is there are not 47 months in a year. In the documentation you will also find lowercasem
for “minute-of-hour”. As you correct the case of the letters in the format pattern string, you will receive other exceptions until you end up with eitheryyyy-MM-dd HH:mm:ss
oruuuu-MM-dd HH:mm:ss
(lowercaseyyyy
is year or era whileuuuu
is a signed year, both work for years after year 0).Links
java.time
.DateTimeFormatter
documentation spelling out the uppercase and lowercase letters of format pattern strings.