Android - Convert GMT time to Locale time - java

I am trying to convert UTC time to user's Locale time. However, I am getting back the same UTC time.
Apparently, setting the time zone to locale/default does not work.
Another method seems to be available using Instant, but requires API level 26.
This is my input date in string: "2020-01-16T19:44:48.303+0000".
I am expecting to have the date and time in this format: "M/dd/yy - h:mm aa"
private String toLocaleTime(String timeStr){
// Date date;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+0000'");
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String localeTime = "";
try {
//date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).parse(timeStr);
localeTime = simpleDateFormat.format(simpleDateFormat.parse(timeStr));
} catch (ParseException e) {
e.printStackTrace();
}
//String str = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).format(date);
Log.d("LocaleTime", ""+ localeTime);
return localeTime;
}

java.time
A Locale has nothing to do with the content of a date-time object. A locale only comes into the picture when generating text to represent the value of the date-time object. I suspect your intention is to adjust from an offset-from-UTC of hours-minutes-seconds to the wall-clock time used by the people of a particular region (a time zone).
Never use SimoleDateFormat or Date or Calendar. These terrible date-time classes were supplanted by java.time years ago. For Android before 26, add the ThreeTenABP library to your project.
This is my input date in string: "2020-01-16T19:44:48.303+0000"
Tip: The java.time classes and other date-time frameworks work better if you include the colon character between the hours and seconds in the offset: +00:00.
If all your inputs have the same offset, replace that part of the string.
String input = "2020-01-16T19:44:48.303+0000".replace( "+0000" , "+00:00" ) ;
Parse as an Instant, a moment in UTC.
Instant instant = Instant.parse( input ) ;
Generate a string in your desired format. Do you really want one-digit month with two digit day? And one digit hour with two digit minute?
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/dd/uu - h:mm a" ).withLocale( locale ) ;
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
String output = instant.atZone( z ).format( z ) ;
I suggest you instead let java.time automatically localize for you with DateTimeFormatter.ofLocalizedDateTime.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

You tell the parsing date formatter to parse using UTC time zone, the tell the formatting date formatter to format using the default time zone (by not telling it anything):
String input = "2020-01-16T19:44:48.303+0000";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+0000'");
inputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = inputFormat.parse(input);
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
// Not needed: outputFormat.setTimeZone(TimeZone.getDefault());
String output = outputFormat.format(date);
System.out.println("input: " + input);
System.out.println("output: " + output);
System.out.println(new SimpleDateFormat("zzzz XX").format(date));
Output
input: 2020-01-16T19:44:48.303+0000
output: 2020-01-16T14:44:48.303
Eastern Standard Time -0500

Related

I am having a problem with changing my date format

Hello guys I am having a problem in changing the date from one form to another. I have searched through stack overflow and made one solution but it is giving wrong result.
As I have date in this format:
2019-04-16 05:50:44
and I wanna convert it to this format
Apr 4
I made this code for conversion
SimpleDateFormat spf=new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
Date newDate=spf.parse("2019-04-16 05:50:44");
spf= new SimpleDateFormat("MMM dd");
String date = spf.format(newDate);
And the result I am getting is Jan 16 and I don't know why ...
Thanks in advance
From the SimpleDateFormat documentation: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
M Month in year
m Minute in hour
So, your code should be:
SimpleDateFormat spf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date newDate=spf.parse("2019-04-16 05:50:44");
spf= new SimpleDateFormat("MMM dd");
String date = spf.format(newDate);
tl;dr
LocalDateTime // Represent a date and time-of-day but without a time zone or offset-from-UTC.
.parse(
"2019-04-16 05:50:44".replace( " " , "T" ) // Comply with ISO 8601 standard format by replacing the SPACE in the middle with a `T`.
) // Returns an immutable `LocalDateTime` object.
.format( // Generate a `String` containing text representing the value of this date-time object.
DateTimeFormatter.ofPattern( "MMM dd" , Locale.US ) // The Locale determines the human language and cultural norms used in localizing the words and formatting generated to the resulting text.
) // Returns a `String`.
Apr 16
java.time
You are using terrible date-time classes that were supplanted years ago by the java.time classes defined in JSR 310.
Convert input to comply with ISO 8601 standard.
String input = "2019-04-16 05:50:44".replace( " " , "T" ) ;
Parse as a LocalDateTime as the input lacks indication of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
You want just the month and day, so use the MonthDay class. I suspect you could make use of this class in other parts of your code.
MonthDay md = MonthDay.from( ldt ) ;
Generate a string in localized format.
Locale locale = Locale.CANADA_FRENCH; // Or Locale.US etc.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM dd" , locale );
String output = md.format( f );
Dump to console.
System.out.println( "md.toString(): " + md );
System.out.println( "output: " + output );
md.toString(): --04-16
output: avr. 16
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

How to convert a string to date with UTC/GMT timezone

I have an android app that receives a string in this format:"MM-dd-yyyy HH:mm:ss" from my server. I want to convert this string to a Date object with UTC as timezone since the time in the string is UTC. I've already checked several similar questions but didn't find my answer
Here is what I'm using currently:
SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
Date date = new Date();
try {
date = format.parse(itemContent [3]);
entity.setValidTill(date);
}catch (Exception e){
}
But what it does when I print that date with Log is show it as:
Sun Aug 27 15:00:00 GMT+04:00 2017
I want it to be:
Sun Aug 27 15:00:00 GMT 00:00 2017
So here is the main question how to get DateTime for UTC using a string with format as above?
Edit:
Just put it in a better context. I'm trying to get users to see the difference between current datetime & the that datetime saved in server. So my solution was to get gmt time for users & compare with the server time(which is gmt) so everyone see same difference regardless of their timezone. With C# you can get DateTime.UtcNow while with java I couldn't find an alternative
Briefly, as your Question is really a duplicate of many others…
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
Parse your input string as a LocalDateTime as it lacks any indicator of offset-from-UTC or time zone.
Define a formatter to parse your input string.
String input = "08-27-2017 15:00:00" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ldt.toString(): 2017-08-27T15:00
A LocalDateTime is not a moment on the timeline, only a rough idea about a range of possible moments. Has no meaning without the context of an offset (or time zone).
If you are certain that input was intended for UTC, assign the constant ZoneOffset.UTC for a OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
odt.toString(): 2017-08-27T15:00Z
To calculate a delta between that moment and the current moment, use the Period class for coarser granularity in your span of time, or Duration for finer granularity. Both classes generate strings in standard ISO 8601 format of PnYnMnDTnHnMnS.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC ) ;
Duration d = Duration.between( odt , now ) ;
now.toString(): 2017-08-27T21:16:56.396Z
d.toString(): PT6H16M56.396S
See this code run live at IdeOne.com.
In the standard strings seen above, the Z is short for Zulu and means UTC.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
just add this code under the first line of your code:
format.setTimeZone(TimeZone.getTimeZone("UTC"));

getTimeInMillis() in java [duplicate]

I have a problem in converting the date in java, don't know where i am going wrong...
String dateStr = "2011-12-15";
String fromFormat = "yyyy-mm-dd";
String toFormat = "dd MMMM yyyy";
try {
DateFormat fromFormatter = new SimpleDateFormat(fromFormat);
Date date = (Date) fromFormatter.parse(dateStr);
DateFormat toformatter = new SimpleDateFormat(toFormat);
String result = toformatter.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
Input date is 2011-12-15 and I am expecting the result as "15 December 2011", but I get it as "15 January 2011"
where am I going wrong?
Your fromFormat uses minutes where it should use months.
String fromFormat = "yyyy-MM-dd";
I think the fromFormat should be "yyyy-MM-dd".
Here is the format:
m == Minute in Hour
M == Month in Year
More: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
From format should be:
String fromFormat = "yyyy-MM-dd"
Look at the javadoc of SimpleDateFormat and look at what the m represents. Not months as you think but minutes.
String fromFormat = "yyyy-MM-dd";
m in SimpleDateFormat stands for minutes, while M stands for month. Thus your first format should be yyyy-MM-dd.
tl;dr
LocalDate.parse( "2011-12-15" ) // Date-only, without time-of-day, without time zone.
.format( // Generate `String` representing value of this `LocalDate`.
DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG ) // How long or abbreviated?
.withLocale( // Locale used in localizing the string being generated.
new Locale( "en" , "IN" ) // English language, India cultural norms.
) // Returns a `DateTimeFormatter` object.
) // Returns a `String` object.
15 December 2011
java.time
While the accepted Answer is correct (uppercase MM for month), there is now a better approach. The troublesome old date-time classes are now legacy, supplanted by the java.time classes.
Your input string is in standard ISO 8601 format. So no need to specify a formatting pattern for parsing.
LocalDate ld = LocalDate.parse( "2011-12-15" ); // Parses standard ISO 8601 format by default.
Locale l = new Locale( "en" , "IN" ) ; // English in India.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( l );
String output = ld.format( f );
Dump to console.
System.out.println( "ld.toString(): " + ld );
System.out.println( "output: " + output );
ld.toString(): 2011-12-15
output: 15 December 2011
See live code in IdeOne.com.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Well this may not be your case but may help someone. In my case after conversion, day of month and month set 1. So whatever date is, after conversion i get 1 jan which is wrong.
After struggling i found that in date format i have used YYYY instead of yyyy. When i changed all caps Y to y it works fine.

Date time String + TimeZone

I have a String representation of a local date time, and a Java TimeZone.
I am trying to get output in the format MM/dd/yyyy HH:mm:ssZ but I can't figure out how to create a Calendar or JodaTime object with the correct date time and timezone. How do you get a TimeZone converted to a value that can be parsed by SimpleDateFormat 'Z' or 'z'?
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
String startDate = "08/14/2014 15:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Calendar cal = Calendar.getInstance(tz);
cal.setTime(sdf.parse(startDate));
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ssZ");
and
sdfZ.format(cal.getTime())
returns
08/14/2014 15:00:00-0400
which is EST.
Is the only workaround to create a Calendar or Joda DateTime and set the individual year/month/day/hour/min values by parsing the string "08/14/2014 15:00:00" ?
Calendar getTime() - Returns a Date object representing this Calendar's time value (millisecond offset from the Epoch(01-01-1970 00:00 GMT)") irrespective of which timezone you are displaying. But hour of day in different TimeZone will be different. get(Calendar.HOUR_OF_DAY)
You should try
sdfZ.setTimeZone(tz);
tl;dr
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Chicago" ) ) ;
String output = zdt.toInstant().toString() ;
2016-12-03T10:15:30Z
java.time
Both the java.util.Calendar class and the Joda-Time library have been supplanted by the java.time classes.
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
Call toString to generate a String in standard ISO 8601 format. For example, 2011-12-03T10:15:30Z. This format is good for serializing date-time values for data storage or exchange.
String output = instant.toString(); // Ex: 2011-12-03T10:15:30Z
Time zone
Assign a time zone.
ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdt = instant.atZone( z );
As a shortcut, you can skip over using Instant.
ZonedDateTime zdt = ZonedDateTime.now( z );
Calling toString on ZonedDateTime gets you an extended version of standard ISO 8601 format where the name of the time zone is appended in square brackets. For example, 2007-12-03T10:15:30+01:00[Europe/Paris].
String output = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
DateTimeFormatter
The DateTimeFormatter class has a predefined formatter constant for your desired output: DateTimeFormatter.ISO_LOCAL_DATE_TIME
String output zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

How to include milliseconds in a formatted date string?

Hi I am coding the following:
String sph=(String) android.text.format.DateFormat.format("yyyy-MM-dd_hh-mm-ss_SSS", new java.util.Date());
I want the current date and time and milliseconds
what it gives me is:
2011-09-01_09-55-03-SSS
The SSS is not converting back to milliseconds...
Does anyone know why and what should it be to get the milliseconds in 3 position?
Thanks
Use the following:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss_SSS");
String dateString = formatter.format(new java.util.Date());
tl;dr
ZonedDateTime // Represent a moment in the wall-clock time used by the people of a certain region (a time zone).
.now() // Capture current moment. Better to pass optional argument for `ZoneId` (time zone). Returns a `ZonedDateTime` object.
.format( // Generate a `String` with text in a custom formatting pattern.
DateTimeFormatter.ofPattern( "uuuu-MM-dd_HH-mm-ss-SSS" )
) // Returns a `String` object.
2018-08-26_15-43-24-895
Instant
You are using troublesome old legacy date-time classes. Instead use the java.time classes.
If you want the date-time in UTC, use the Instant class. This class holds nanosecond resolution, more than enough for milliseconds.
Instant instant = Instant.now();
String output = instant.toString();
That toString method uses the DateTimeFormatter.ISO_INSTANT formatter which prints 0, 3, 6, or 9 digits in the decimal fraction, as many as needed appropriate to the actual data value.
In Java 8 the current moment is captured only up to milliseconds but a new implementation of Clock in Java 9 may capture up to nanoseconds. So truncate to milliseconds if that is your requirement. Specify your desired truncation by a TemporalUnit as implemented in ChronoUnit.MILLIS.
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS );
ZonedDateTime
If you want a specify time zone, apply a ZoneId to get a ZonedDateTime.
Instant instant = Instant.now();
instant.toString(): 2018-08-26T19:43:24.895621Z
Instant instantTruncated = instant.truncatedTo( ChronoUnit.MILLIS );
instantTruncated.toString(): 2018-08-26T19:43:24.895Z
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
String output = zdt.toString();
2018-08-26T15:43:24.895621-04:00[America/Montreal]
Again if you want other formats, search Stack Overflow for DateTimeFormatter.
DateTimeFormatter
If you want to force three digits for milliseconds, even if the value is all zeros, specify a custom formatting pattern using DateTimeFormatter class.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd_HH-mm-ss-SSS" ) ;
String output = zdt.format( f ) ;
2018-08-26_15-43-24-895
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
Try using the same format with SimpleDateFormat

Categories