This question already has answers here:
Strange Java Timezone Date Conversion Problem
(3 answers)
Closed 4 years ago.
I am trying to convert date string to UTC format from another time zone in Java. we have only time zone offset like "-06:00". Can any one help me how to convert the date time to UTC format using time zone offset.
Thanks
This for java version 1.7 . I have tried with following snippet but receiving the same input as output.
String dateInString = "02/04/2019 18:17:15";
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = formatter.parse(dateInString);
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("+5:30"));
String dateStr = dateFormat.format(date);
System.out.println(dateStr);
Output
02/04/2019 18:17:15
Unfortunately, TimeZone.getTimeZone(String ID) returns:
the specified TimeZone, or the GMT zone if the given ID cannot be understood.
The "+5:30" time zone cannot be understood, so you get GMT.
Change to "GMT+5:30" will make your code work, i.e. it'll print:
02/04/2019 23:47:15
See the javadoc of TimeZone for valid ID syntax:
The syntax of a custom time zone ID is:
CustomID:
GMT Sign Hours : Minutes
GMT Sign Hours Minutes
GMT Sign Hours
Sign: one of
+ -
Hours:
Digit
Digit Digit
Minutes:
Digit Digit
Digit: one of
0 1 2 3 4 5 6 7 8 9
As you can see, it must always start with GMT.
Related
This question already has answers here:
SimpleDateFormat producing wrong date time when parsing "YYYY-MM-dd HH:mm"
(5 answers)
Closed 4 years ago.
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.
The only problem with your code is DateFormat
please check.
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
String dateString = "2018-02-21 15:47:35";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = df.parse(dateString);
long time = date.getTime();
System.out.println(time);
System.out.println(new Date(time));
System.out.println(date);
I'm in PKT so output would differ...
1519228055000
Wed Feb 21 20:47:35 PKT 2018
Wed Feb 21 20:47:35 PKT 2018
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:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
date = LocalDateTime.parse("2018-02-21 15:47:35", dtf)
.atOffset(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
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 modern DateTimeFormatter:
final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-DD HH:MM:SS");
LocalDateTime.parse(dateString, dtf);
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 match MM in the format. If you haven’t figured out yet, check the documentation. It says that uppercase M 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 lowercase m 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 either yyyy-MM-dd HH:mm:ss or uuuu-MM-dd HH:mm:ss (lowercase yyyy is year or era while uuuu is a signed year, both work for years after year 0).
Links
Oracle tutorial: Date Time explaining how to use java.time.
DateTimeFormatter documentation spelling out the uppercase and lowercase letters of format pattern strings.
Also can be done via java8 time library:
String dateString = "2018-02-21 15:47:35";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
dateTimeFormatter.withZone(ZoneId.of("UTC"));
LocalDateTime parsedDateTime = LocalDateTime.from(dateTimeFormatter.parse(dateString));
ZonedDateTime timeAtYourZone = parsedDateTime.atZone(ZoneId.systemDefault());
System.out.println(timeAtYourZone.toInstant().toEpochMilli());
System.out.println(timeAtYourZone);
Your pattern must be yyyy-MM-dd HH:mm:ss, as the other answers told you:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
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:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneOffset.UTC);
long epochMilli = Instant.from(fmt.parse("2018-02-21 15:47:35")).toEpochMilli();
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.
This question already has answers here:
How to include milliseconds in a formatted date string?
(3 answers)
Closed 5 years ago.
I have a date that I want to change into a different format.
Current format: Fri Apr 07 08:21:19 MDT 2017
Desired format: 2017-04-07T13:28:41.00MDT. I want to have the desired format output as a string.
I am currently doing this:
DateTimeFormatter sourceFormat = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu");
ZonedDateTime dateParsed = ZonedDateTime.parse(dateStr, sourceFormat);
String fullDateTimeStr = fullDateTime.format(dateParsed);
The formatting is correct, but the main issue I'm having is preserving the fractional seconds (the two numbers right before the time zone.) I know that the date I am receiving has the ms/fractional seconds preserved because when I print out long epoch = ((Date) date).getTime(); I get the epoch time and I can convert it (using an online conversion tool) and it shows the correct date/time with ms.
What's going on?
DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSz");
ZonedDateTime zdt = ZonedDateTime.now();
System.out.println(zdt.format(targetFormat));
Sample output:
2017-04-14T21:19:58.409CEST
You need SSS in the format pattern for the milliseconds.
Please consider whether you need the three or four letter time zone abbreviations that are often ambiguous. I would prefer to use DateTimeFormatter.ISO_ZONED_DATE_TIME for an output like 2017-04-14T21:22:49.344+02:00[Europe/Berlin]. This also saves you from building the pattern string yourself.
This question already has answers here:
How to find difference between two Joda-Time DateTimes in minutes
(4 answers)
Closed 7 years ago.
I have to implement a java program to make the difference between two hours. The problem is that my "hour pattern" is like this:
MM/dd/yyyy HH:mm:ss.SSS
I have to consider ms, too.
I tried using joda:
String sDateStart = "2015/10/14 22:37:28.648";
String sDateFiish = "2015/10/14 22:39:13.573";
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
Date dt1 = format.parse(sDateFiish);
Date dt2 = format.parse(sDateStart);
DateTime start = new DateTime(dt1);
DateTime finish = new DateTime(dt2);
System.out.println(Days.daysBetween(start, finish));
System.out.println(Minutes.minutesBetween(start, finish));
System.out.println(Seconds.secondsBetween(start, finish));
Is there any method to consider the ms?
If you are using Java API itself. In Date class we have getTime method which gives time in millisecond
getTime()
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
System.out.println((long)(dt1.getTime() - dt2.getTime()));
If you wanna continue using Joda Time API use Duration. as mentioned by Sotirios Delimanolis
This question already has answers here:
Unix epoch time to Java Date object
(7 answers)
Closed 5 years ago.
How can I convert minutes from Unix timestamp to date and time in java? For example, timestamp 1372339860 correspond to Thu, 27 Jun 2013 13:31:00 GMT.
I want to convert 1372339860 to 2013-06-27 13:31:00 GMT.
Edit: Actually I want it to be according to US timing GMT-4, so it will be 2013-06-27 09:31:00.
You can use SimlpeDateFormat to format your date like this:
long unixSeconds = 1372339860;
// convert seconds to milliseconds
Date date = new java.util.Date(unixSeconds*1000L);
// the format of your date
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
// give a timezone reference for formatting (see comment at the bottom)
sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT-4"));
String formattedDate = sdf.format(date);
System.out.println(formattedDate);
The pattern that SimpleDateFormat takes if very flexible, you can check in the javadocs all the variations you can use to produce different formatting based on the patterns you write given a specific Date. http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Because a Date provides a getTime() method that returns the milliseconds since EPOC, it is required that you give to SimpleDateFormat a timezone to format the date properly acording to your timezone, otherwise it will use the default timezone of the JVM (which if well configured will anyways be right)
Java 8 introduces the Instant.ofEpochSecond utility method for creating an Instant from a Unix timestamp, this can then be converted into a ZonedDateTime and finally formatted, e.g.:
final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
final long unixTime = 1372339860;
final String formattedDtm = Instant.ofEpochSecond(unixTime)
.atZone(ZoneId.of("GMT-4"))
.format(formatter);
System.out.println(formattedDtm); // => '2013-06-27 09:31:00'
I thought this might be useful for people who are using Java 8.
You need to convert it to milliseconds by multiplying the timestamp by 1000:
java.util.Date dateTime=new java.util.Date((long)timeStamp*1000);
This question already has answers here:
How can I get the current date and time in UTC or GMT in Java?
(33 answers)
Closed 9 years ago.
What is the function to get the current UTC time. I have tried with System.getCurrentTime but i get the current date and time of the device.
Thanks
System.currentTimeMillis() does give you the number of milliseconds since January 1, 1970 00:00:00 UTC. The reason you see local times might be because you convert a Date instance to a string before using it. You can use DateFormats to convert Dates to Strings in any timezone:
DateFormat df = DateFormat.getTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("gmt"));
String gmtTime = df.format(new Date());
Also see this related question.