This question already has answers here:
Convert UTC date to current timezone
(5 answers)
Timezone conversion
(13 answers)
Closed 2 years ago.
I have string timestamp like
2020-05-25 08:03:24
I have tried to split the String using " " (a whitespace) as delimiter to get two Strings "2020-05-25" and "08:03:24". After that, I used substring to get the hours and added 7 to have jakarta time.
But when it is 17:01:00 for example, my calculated date is wrong.
The date given is in UTC.
I want to convert it become timezone [ASIA/Jakarta] how to convert utc timestamp become asia jakarta time?
You can use java.time if you are using Java 8 or higher.
The library provides handy possibilities of converting datetimes that don't have information about a time zone (like your example String) to a zone and handle conversions from one zone to another.
See this example:
public static void main(String[] args) {
// datetime string without a time zone or offset
String utcTimestamp = "2020-05-25 08:03:24";
// parse the datetime as it is to an object that only knows date and time (no zone)
LocalDateTime datetimeWithoutZone = LocalDateTime.parse(utcTimestamp,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// convert it to a zone-aware datetime object by adding a zone
ZonedDateTime utcZdt = datetimeWithoutZone.atZone(ZoneId.of("UTC"));
// print the datetime in utc once
System.out.println(utcZdt);
// then convert the zoned datetime to a different time zone
ZonedDateTime asiaJakartaZdt = utcZdt.withZoneSameInstant(ZoneId.of("Asia/Jakarta"));
// and print the result
System.out.println(asiaJakartaZdt);
}
The output is
2020-05-25T08:03:24Z[UTC]
2020-05-25T15:03:24+07:00[Asia/Jakarta]
Related
This question already has answers here:
SimpleDateFormat returns wrong time zone during parse
(2 answers)
SimpleDateFormat parse loses timezone [duplicate]
(3 answers)
DateFormat parse - not return date in UTC
(1 answer)
Get date from device and convert it to GMT+4
(1 answer)
Closed 3 years ago.
Given these two date Strings, I am trying to create a menu that allows you to select from the two dates (these are returned from an API with the users timezone):
2019-12-20T00:00:00.000-05:00
2019-12-19T00:00:00.000-05:00
I use the following code to parse the date string in the users preferred timezone (I have downloaded this locally to their devices). I have verified that the TZUtils.getUsersTimeZone() returns this timezone: America/New York which has an offset of -5.
fun getDateForString(date: String): Date {
val parser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
parser.timeZone = TZUtils.getUsersTimeZone()
return parser.parse(date)
}
When these dates are parsed, they are parsed into my local time time (offset -6) and not in the users local time zone (-5), even though I specify to use the users local time zone. When I create the popup menu, I used the following code to show the dates
public String getStringForDate(Date date) {
DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
return dateFormat.format(date);
}
And this returns me the wrong dates to select from (the dates are based on my timezone and not the users). Furthermore, when I select the data from the menu, the function I use to filter data based on if it is the same day as the selected date doesn't work because it uses my timezone as well. How do I fix this or do I just "assume" this will work for users since their devices are in their timezones?
You can use the modern java.time package instead and specially ZonedDateTime that handles time zones.
String str = "2019-12-20T00:00:00.000-05:00";
ZonedDateTime zonedDateTime = ZonedDateTime.parse(str);
And when showing it in the UI use DateTimeFormatter to convert it to a formatted string
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
or with some custom format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
which will give you for the 2 formats
System.out.println(formatter.format(zonedDateTime));
2019-12-20T00:00-05:00
2019-12-20 00:00
SimpleDateFormat.getDateInstance(...) will give you an instance in the JVM's default time zone.
Set the time zone to whatever you need it to be.
DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
dateFormat.setTimeZone(/* whatever */);
return dateFormat.format(date);
This question already has answers here:
How to Format ISO-8601 in Java
(3 answers)
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Closed 4 years ago.
I know there are alot of these, but I can'e seem to find the magic string for this date format:
String textDate = "2018-04-25T18:23:57.556Z";
My code is:
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
simpleDateFormat.parse(textDate)
What's weird is there is a "Z" in the date string itself, so I am not sure how the timezone works on this one.
If I change the date format to:
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
It works, but I am not sure how to get the time zone then...
Z = UTC
The literal "Z" is actually part of the ISO 8601 datetime standard for UTC times. When "Z" (Zulu) is tacked on the end of a time, it indicates that that time is UTC, so really the literal Z is part of the time.
The java.time classes use the ISO 8601 standard formats by default when parsing/generating strings. The Instant class represents a moment in UTC, a perfect fit for your input string.
Instant instant = Instant.parse( "2018-04-25T18:23:57.556Z" ) ;
This question already has answers here:
Convert a date format in epoch
(6 answers)
Closed 5 years ago.
I am very new to Java and coding in general - I have some code which returns a timestamp in the following format yyyy.MM.dd HH:mm:ss:ms which is shown below:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:sss");
This returns:
2017.07.19 11:42:30:423
Is there a way to edit the "SimpleDateFormat formatter" code above to return the date/time as an epoch timestamp that includes milliseconds so that the value returned is formatted as per the below?
1500464550423
I'm hoping that I can amend the ("yyyy.MM.dd HH:mm:ss:sss") part of the SimpleDateFormat formatter code to do this.
Any help or advice is much appreciated.
Thanks
You have a simple error in the use of case in your format pattern string (these are case sensitive). And worse, you are using the old and troublesome SimpleDateFormat class. One of the many problems with it is it’s not telling you what the problem is.
So I recommend you use the modern Java date and time API instead (I am deliberately using your format pattern string verbatim):
String receivedTimetamp = "2017.07.19 11:42:30:423";
DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss:sss");
LocalDateTime dateTime = LocalDateTime.parse(receivedTimetamp, parseFormatter);
System.out.println(dateTime);
This code throws an IllegalArgumentException: Too many pattern letters: s. I hope this calls your awareness to the fact that you are using two s’s for seconds and three s’s for fraction of second. If it still isn’t clear, the documentation will tell you that lowercase s is correct for seconds, while you need uppercase S for the fraction. Let’s repair:
DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss:SSS");
Now the code prints 2017-07-19T11:42:30.423, so we have managed to parse the string correctly.
To convert to milliseconds we are still missing a crucial piece of information: in what time zone should the timestamp be interpreted? I think the two obvious guesses are UTC and your local time zone (which I don’t know). Try UTC:
System.out.println(dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli());
This produces 1500464550423, which is the number you asked for. I suppose we’re done.
If you wanted your JVM’s time zone setting instead, use .atZone(ZoneId.systemDefault()) instead of .atOffset(ZoneOffset.UTC), but beware that the setting may be altered by other software running in the same JVM, so this is fragile.
First of all, check the documentation of SimpleDateFormat. The pattern that corresponds to milliseconds is an uppercase S, while the lowercase s corresponds to seconds. The problem is that SimpleDateFormat usually doesn't complain and try to parse 423 as seconds, adding this amount to your end date (giving an incorrect result).
Anyway, SimpleDateFormat just parses a String to a java.util.Date or formats the Date to a String. If you want the epoch millis value, you must get it from the Date object:
// input string
String s = "2017.07.19 11:42:30:423";
// use correct format ('S' for milliseconds)
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:SSS");
// parse to a date
Date date = formatter.parse(s);
// get epoch millis
long millis = date.getTime();
System.out.println(millis); // 1500475350423
The problem is that SimpleDateFormat uses the system's default timezone, so the final value above (1500475350423) will be equivalent to the specificed date and time in my system's timezone (which can be different from yours - just for the record, my system's default timezone is America/Sao_Paulo). If you want to specify in what timezone this date is, you need to set in the formatter (before calling parse):
// set a timezone to the formatter (using UTC as example)
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
With this, the result for millis will be 1500464550423 (the equivalent to the specificed date and time in UTC).
To do the opposite (create a date from the millis value), you must create a Date object and then pass it to the formatter (also taking care of setting a timezone to the formatter):
// create date from millis
Date date = new Date(1500464550423L);
// use correct format ('S' for milliseconds)
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:SSS");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
// format date
String formatted = formatter.format(date);
Java new date/time API
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.
If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).
The code below works for both.
The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.
As the input String has no timezone information (only date and time), first I parsed it to a LocalDateTime (a class that represents a date and time without timezone). Then I convert this date/time to a specific timezone and get the millis value from it:
// input string
String s = "2017.07.19 11:42:30:423";
// use correct format ('S' for milliseconds)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss:SSS");
// as the input string has no timezone information, parse it to a LocalDateTime
LocalDateTime dt = LocalDateTime.parse(s, formatter);
// convert the LocalDateTime to a timezone
ZonedDateTime zdt = dt.atZone(ZoneId.of("Europe/London"));
// get the millis value
long millis = zdt.toInstant().toEpochMilli(); // 1500460950423
The value is now 1500460950423, equivalent to the specified date and time in London timezone.
Note that the API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.
You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
You can also use ZoneOffset.UTC constant if you want to use UTC.
To do the opposite, you can get the millis value to create an Instant, convert it to a timezone and pass it to the formatter:
// create Instant from millis value
Instant instant = Instant.ofEpochMilli(1500460950423L);
// use correct format ('S' for milliseconds)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss:SSS");
// convert to timezone
ZonedDateTime z = instant.atZone(ZoneId.of("Europe/London"));
// format
String formatted = z.format(formatter);
First advice is to move to java8 java.time API instead of learning the broken java.date API
then do:
Instant i = Instant.now();
System.out.println(i.toEpochMilli());
in your case you can do:
LocalDateTime myldt = LocalDateTime.parse("2017-06-14 14:29:04",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(myldt.toInstant(ZoneOffset.UTC).toEpochMilli());
note that as soon as you play more with the api you will find more ways to achieve the same thing, at the end you will end invoking toEpochMilli
String strDate = "Jun 13 2003 23:11:52.454 UTC";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM dd yyyy HH:mm:ss.SSS zzz");
ZonedDateTime zdt = ZonedDateTime.parse(strDate,dtf);
System.out.println(zdt.toInstant().toEpochMilli()); // 1055545912454
You can try
long time = System.currentTimeMillis();
If you have a java.util.Date then invoking getTime() will return the number of millis since the epoch. For example:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:sss");
Date dateToBeFormatted = new Date();
// this will print a datetime literal on the above format
System.out.println(formatter.format(dateToBeFormatted));
// this will print the number of millis since the Java epoch
System.out.println(dateToBeFormatted.getTime());
The key point here is that in order to get the number of millis since the epoch you do not need a SimpleDateFormatter because the number of millis since the epoch is a property of the Date.
This question already has answers here:
Converting a date string to a DateTime object using Joda Time library
(10 answers)
Closed 6 years ago.
Is there a way to convert a date in the format "YYYY-MM-dd" to "YYYY-MM-dd HH:mm:ss" using Joda?
Eg: "2016-01-21" to "2016-01-21 00:00:00"
Use DateTimeFormat class from Joda API. It helps you to format the date to the formatting of your choice. You can simply provide the format you want, like in this case you want "YYYY-MM-dd HH:mm:ss". The code below works with JodaTime 2.0 and above.
DateTime date = DateTime.parse("2016-01-21", DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss"));
There are two things in play here, first we need to parse the existing string into a DateTime object, which is done via the parse method, it also allows an additional argument, to convert the output into a different format. The longer but easier to understand implementation is given below.
DateTime date = DateTime.parse("2016-01-21");
DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss");
date = formatter.parseDateTime(string);
Your question is not clear:
Do you want to just format "something representing a date" into a string with time of "00:00:00"?
Or are you trying to convert "something representing a date" into "something representing a date+time, with 00:00:00 as time"?
Or are you trying to convert a java.util.Date to a Joda org.joda.time.DateTime by ignoring the original time and set time to 00:00:00?
Or are you trying to convert a string of date with format of "YYYY-MM-dd" to another String with date+time, with 00:00:00 as time?
Or something else?
In Joda, the proper way to represent a date is by LocalDate, and the proper way to represent a "date + time" information (but not a instant of time) is by LocalDateTime. DateTime is representing a instant of time. With these basic understanding:
Answer for Q1:
String result = DateTimeFormat.forPattern("YYYY-MM-dd", myLocalDate);
Answer for Q2:
LocalDateTime result = myLocalDate.toLocalDateTime(LocalTime.MIDNIGHT);
Answer for Q3:
DateTime result = new DateTime(javaUtilDate).withTimeAtStartOfDay();
Answer for Q4:
String result = dateString + " 00:00:00";
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);