Date formating issue having + sign - java

I have date 2016-03-30T23:59:59.000000+0000. May I know what format it is in.
because if I use yyyy-MM-dd'T'HH:mm:ss.SSS, it is throwing an exception

SimpleDateFormat gives you the answer:
yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ

If you really have microseconds different from zero then I strongly advise not to use SimpleDateFormat but Java-8-Time-API or another time library which can handle microseconds. And this is not the only case where the old API proves to be very limited.
Negative example for SimpleDateFormat (broken, milliseconds disappear!!!):
String input = "2016-03-30T23:59:59.123456+0530";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(sdf.parse(input))); // 2016-03-30T18:32:02.000456+0000
Java-8-example (works):
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ");
OffsetDateTime odt = OffsetDateTime.parse(input, dtf);
System.out.println(odt); // 2016-03-30T23:59:59.123456+05:30
If you never have microseconds but only milliseconds and want to insist on using the old API then you might try following hack:
String input = "2016-03-30T23:59:59.123000+0530";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'xxx'Z");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
sdf2.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf2.format(sdf1.parse(input.replace("000", "xxx"))));
2016-03-30T18:29:59.123+0000
However, this "solution" breaks for year 2000 (you can find a better one by further string preprocessing), and eventually available microseconds get lost. So using SimpleDateFormat is a bad idea here.

Related

Date value converted from Calendar outputs different format than String [duplicate]

I have the following scenario :
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(dateFormat.parse("31/05/2011"));
gives an output
Tue May 31 00:00:00 SGT 2011
but I want the output to be
31/05/2011
I need to use parse here because the dates need to be sorted as Dates and not as String.
Any ideas ??
How about:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(dateFormat.format(dateFormat.parse("31/05/2011")));
> 31/05/2011
You need to go through SimpleDateFormat.format in order to format the date as a string.
Here's an example that goes from String -> Date -> String.
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("31/05/2011");
System.out.println(dateFormat.format(date)); // prints 31/05/2011
// ^^^^^^
Use the SimpleDateFormat.format
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
String sDate= sdf.format(date);
You can use simple date format in Java using the code below
SimpleDateFormat simpledatafo = new SimpleDateFormat("dd/MM/yyyy");
Date newDate = new Date();
String expectedDate= simpledatafo.format(newDate);
It makes no sense, but:
System.out.println(dateFormat.format(dateFormat.parse("31/05/2011")))
SimpleDateFormat.parse() = // parse Date from String
SimpleDateFormat.format() = // format Date into String
If you want to simply output a date, just use the following:
System.out.printf("Date: %1$te/%1$tm/%1$tY at %1$tH:%1$tM:%1$tS%n", new Date());
As seen here. Or if you want to get the value into a String (for SQL building, for example) you can use:
String formattedDate = String.format("%1$te/%1$tm/%1$tY", new Date());
You can also customize your output by following the Java API on Date/Time conversions.
java.time
Here’s the modern answer.
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
DateTimeFormatter displayFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.forLanguageTag("zh-SG"));
String dateString = "31/05/2011";
LocalDate date = LocalDate.parse(dateString, sourceFormatter);
System.out.println(date.format(displayFormatter));
Output from this snippet is:
31/05/11
See if you can live with the 2-digit year. Or use FormatStyle.MEDIUM to obtain 2011年5月31日. I recommend you use Java’s built-in date and time formats when you can. It’s easier and lends itself very well to internationalization.
If you need the exact format you gave, just use the source formatter as display formatter too:
System.out.println(date.format(sourceFormatter));
31/05/2011
I recommend you don’t use SimpleDateFormat. It’s notoriously troublesome and long outdated. Instead I use java.time, the modern Java date and time API.
To obtain a specific format you need to format the parsed date back into a string. Netiher an old-fashioned Date nor a modern LocalDatecan have a format in it.
Link: Oracle tutorial: Date Time explaining how to use java.time.
You already has this (that's what you entered) parse will parse a date into a giving format and print the full date object (toString).
This will help you.
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
print (df.format(new Date());
I had something like this, my suggestion would be to use java for things like this, don't put in boilerplate code
This looks more compact. Finishes in a single line.
import org.apache.commons.lang3.time.DateFormatUtils;
System.out.println(DateFormatUtils.format(newDate, "yyyy-MM-dd HH:mm:ss"));

Convert yyyy-MM-dd'T'HH:mm:ss.mmm'Z' to normal "HH:mm a" format

I have a problem in displaying the date in my Application.
I am getting timestamp as:
2017-08-02T06:05:30.000Z
But as per this the actual time is:
2017:08:02 11:35 AM
But after converting using my code it displays the time as:
6:00 am
How to show it as current time?
My code is given below:
private static SimpleDateFormat timestampformat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.mmm'Z'");
private static SimpleDateFormat sdftimeformat = new SimpleDateFormat("HH:mm a");
private static SimpleDateFormat getSdftimeformat() {
return sdftimeformat;
}
public static String timeStampConvertToTime(String time) {
Date date1 = null;
try {
date1 = timestampformat.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
String formattedTime = getSdftimeformat().format(date1);
return formattedTime;
}
The first thing is that you're using mm:ss.mmm in your format. According to SimpleDateFormat javadoc, m represents the minutes, so you must change it to mm:ss.SSS because S represents the milliseconds.
Another detail is that the Z in the end is the timezone designator for UTC and it can't be ignored (at least it shouldn't). You must use the corresponding pattern for that, which is X:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
PS: the X pattern was introduced in Java 7. If you're using Java <= 6, the only alternative is to treat Z as a literal (an ugly workaround, I admit) and set the UTC as the timezone used by the parser:
// treat "Z" as literal
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// use UTC as timezone
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
With this, the date will have the value corresponding to 06:05 in UTC. To format the time to your timezone, you must use another SimpleDateFormat with the corresponding timezone:
// output format: hour:minute AM/PM
SimpleDateFormat outputFormat = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
// assuming a timezone in India
outputFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
System.out.println(outputFormat.format(date));
The output will be:
11:35 AM
If you don't set a timezone, it'll use the system's default. But the default can be changed without notice, even at runtime, so it's better to explicity set a specific timezone as above.
I also used java.util.Locale to set the language to English, because some locales can have different symbols for AM/PM. If you don't specify one, it'll use the system default and it's not guaranteed to be one in which the symbols are the ones you need (some locales uses "a.m./p.m." or another different formats, so it's better to use an explicit locale).
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.
To parse the input you can use the ZonedDateTime class, which has full support to timezones and it makes the conversion to another zones very easy. Then you use a DateTimeFormatter to format the output:
// parse the input
ZonedDateTime parsed = ZonedDateTime.parse("2017-08-02T06:05:30.000Z");
// convert to another timezone
ZonedDateTime z = parsed.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
// format output
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
System.out.println(fmt.format(z));
The output will be:
11:35 AM
If the input always has Z in the end, you can also use the Instant class:
// parse the input
Instant instant = Instant.parse("2017-08-02T06:05:30.000Z");
// convert to a timezone
ZonedDateTime z = instant.atZone(ZoneId.of("Asia/Kolkata"));
Note that I used hh for the hours: this will format using values from 1 to 12 (it makes sense because I'm also using the AM/PM designators). If you want values from 0 to 23, use HH instead - check the javadoc for more details.
Also note that the API uses IANA timezones names (always in the format Region/City, like Asia/Kolkata or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CST or IST) 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 the system's default timezone with ZoneId.systemDefault(), but this can be changed without notice, even at runtime, so it's better to explicity use a specific one.
You need to use SimpleDateFormat class and specify the format you want to parse from , like this :
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
long timeStamp = sdf.parse('your_timestamp').getTime();
SimpleDateFormat currentDateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm a", Locale.getDefault());
String time =currentDateFormat.format(timeStamp); // Formatted time in string form
try this your will get result
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'");
// set your format in df variable
SimpleDateFormat df = new SimpleDateFormat(
"HH:mm a");
try {
cal.setTime('your value');
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String localtime = df.format(cal.getTime());
use this for get current time.
Calendar cal =
Calendar.getInstance(TimeZone.getTimeZone("GMT+5:30"));
Date currentLocalTime = cal.getTime();
DateFormat date = new SimpleDateFormat("HH:mm a");
// you can get seconds by adding "...:ss" to it
date.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
String localTime = date.format(currentLocalTime);
change time zone to your time zone
I assume the Z in Rose's timestamp is zulu time, it isn't really correct to hard code the conversion from zulu time to his local time zone (GMT+5:30 we are assuming). It might be OK if it is always returning Z but if it is
military time zones you would need something that can handle all the possible timezones.
This previous question implies there is no built in way to do it. Need to understand where the timestamp is coming from to really answer the question.

SimpleDateFormat sets current day for parsed date

Is there any way to use the following simpleDateFormat:
final SimpleDateFormat simpleDateFormatHour = new SimpleDateFormat("HH:mm:ss z");
and when invoking:
simpleDateFormat.parse("12:32:21 JST");
to return current date on the Date object?
For these example, it will return:
Thu Jan 01 05:32:21 EET 1970
and not:
<<today>> 05:32:21 EET <<currentYear>>
as I need.
No, SimpleDateFormat needs explicity the date in the input string. If you're using Java 8, you can go with a LocalDateTime:
LocalDateTime localDateTime = LocalDate.now().atTime(5, 32, 21);
If you want to include a time-zone, you can use ZonedDateTime.
Construct another SimpleDateFormat to print today's date:
String today = new SimpleDateFormat("yyyy/MM/dd").print(new Date());
(Be careful here: you might want to set the time zone on the SimpleDateFormat, as "today" is different in different time zones).
Update the date format to include year, month and day:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z");
And then prepend the date string with the date you want:
simpleDateFormat.parse(today + " " + "12:32:21 JST");
A better solution using flexible default values (today instead of 1970-01-01) would be in Java-8 with the new built-in date-time-library located in package java.time:
String input = "12:32:21 JST";
String pattern = "HH:mm:ss z";
LocalDate today = LocalDate.now(ZoneId.of("Asia/Tokyo"));
DateTimeFormatter dtf =
new DateTimeFormatterBuilder().parseDefaulting(ChronoField.YEAR, today.getYear())
.parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue()).parseDefaulting(
ChronoField.DAY_OF_MONTH,
today.getDayOfMonth()
).appendPattern(pattern).toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(input, dtf);
System.out.println(zdt); // 2016-12-23T12:32:21+09:00[Asia/Tokyo]
However, I still see a small bug related to the fact that this code makes a hardwired assumption about the used zone BEFORE parsing the real zone so please handle with care. Keep in mind that the current date depends on the zone. But maybe you only need to handle a scenario where just the Japan time is used by users.
Hint: You can also parse in two steps. First step with any kind of fixed default date in order to get the zone information of the text to be parsed. And then you can use this zone information for suggested solution above. An awkward but safe procedure.
You can use this code if you want to change only the year and the day
final SimpleDateFormat simpleDateFormatHour = new SimpleDateFormat("HH:mm:ss z");
Date date = simpleDateFormatHour.parse("12:32:21 JST");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
calendar.set(Calendar.DAY_OF_YEAR, Calendar.getInstance().get(Calendar.DAY_OF_YEAR));
date = calendar.getTime();

SimpleDateFormat pattern based on locale, but forcing a 4-digit year

I need to build a date format like dd/MM/yyyy. It's almost like DateFormat.SHORT, but contains 4 year digits.
I try to implement it with
new SimpleDateFormat("dd//MM/yyyy", locale).format(date);
However for US locale the format is wrong.
Is there a common way to format date that changes pattern based on locale?
Thank you
I would do it like this:
StringBuffer buffer = new StringBuffer();
Calendar date = Calendar.getInstance();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
FieldPosition yearPosition = new FieldPosition(DateFormat.YEAR_FIELD);
StringBuffer format = dateFormat.format(date.getTime(), buffer, yearPosition);
format.replace(yearPosition.getBeginIndex(), yearPosition.getEndIndex(), String.valueOf(date.get(Calendar.YEAR)));
System.out.println(format);
Using a FieldPosition you don't really have to care about wheter the format of the date includes the year as "yy" or "yyyy", where the year ends up or even which kind of separators are used.
You just use the begin and end index of the year field and always replace it with the 4 digit year value and that's it.
java.time
Here’s the modern answer. IMHO these days no one should struggle with the long outdated DateFormat and SimpleDateFormat classes. Their replacement came out in the modern Java date & time API early in 2014, the java.time classes.
I am just applying the idea from Happier’s answer to the modern classes.
The DateTimeFormatterBuilder.getLocalizedDateTimePattern method generates a formatting pattern for date and time styles for a Locale. We manipulate the resulting pattern string to force the 4-digit year.
LocalDate date = LocalDate.of( 2017, Month.JULY, 18 );
String formatPattern =
DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT,
null,
IsoChronology.INSTANCE,
userLocale);
formatPattern = formatPattern.replaceAll("\\byy\\b", "yyyy");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, userLocale);
String output = date.format(formatter);
Example output:
For Locale.US: 7/18/2017.
For each of UK, FRANCE, GERMANY and ITALY: 18/07/2017.
DateTimeFormatterBuilder allows us to get the localized format pattern string directly, without getting a formatter first, that’s convenient here. The first argument to getLocalizedDateTimePattern() is the date format style. null as second argument indicates that we don’t want any time format included. In my test I used a LocalDate for date, but the code should work for the other modern date types too (LocalDateTime, OffsetDateTime and ZonedDateTime).
I have similar way to do this, but I need to get the locale pattern for the ui controller.
So here's the code
// date format, always using yyyy as year display
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
SimpleDateFormat simple = (SimpleDateFormat) dateFormat;
String pattern = simple.toPattern().replaceAll("\\byy\\b", "yyyy");
System.out.println(pattern);
Can you not just use java.text.DateFormat class ?
DateFormat uk = DateFormat.getDateInstance(DateFormat.LONG, Locale.UK);
DateFormat us = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
Date now = new Date();
String usFormat = us.format(now);
String ukFormat = uk.format(now);
That should do what you want to do.

How can I convert a timestamp from yyyy-MM-ddThh:mm:ss:SSSZ format to MM/dd/yyyy hh:mm:ss.SSS format? From ISO8601 to UTC

I want to convert the timestamp 2011-03-10T11:54:30.207Z to 10/03/2011 11:54:30.207. How can I do this? I want to convert ISO8601 format to UTC and then that UTC should be location aware. Please help
String str_date="2011-03-10T11:54:30.207Z";
DateFormat formatter ;
Date date ;
formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");
date = (Date)formatter.parse(str_date);
System.out.println("output: " +date );
Exception :java.text.ParseException: Unparseable date: "2011-03-10T11:54:30.207Z"
Firstly, you need to be aware that UTC isn't a format, it's a time zone, effectively. So "converting from ISO8601 to UTC" doesn't really make sense as a concept.
However, here's a sample program using Joda Time which parses the text into a DateTime and then formats it. I've guessed at a format you may want to use - you haven't really provided enough information about what you're trying to do to say more than that. You may also want to consider time zones... do you want to display the local time at the specified instant? If so, you'll need to work out the user's time zone and convert appropriately.
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static void main(String[] args) {
String text = "2011-03-10T11:54:30.207Z";
DateTimeFormatter parser = ISODateTimeFormat.dateTime();
DateTime dt = parser.parseDateTime(text);
DateTimeFormatter formatter = DateTimeFormat.mediumDateTime();
System.out.println(formatter.print(dt));
}
}
Yes. you can use SimpleDateFormat like this.
SimpleDateFormat formatter, FORMATTER;
formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String oldDate = "2011-03-10T11:54:30.207Z";
Date date = formatter.parse(oldDate.substring(0, 24));
FORMATTER = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss.SSS");
System.out.println("OldDate-->"+oldDate);
System.out.println("NewDate-->"+FORMATTER.format(date));
Output
OldDate-->2011-03-10T11:54:30.207Z
NewDate-->10-Mar-2011 11:54:30.207
Enter the original date into a Date object and then print out the result with a DateFormat. You may have to split up the string into smaller pieces to create the initial Date object, if the automatic parse method does not accept your format.
Pseudocode:
Date inputDate = convertYourInputIntoADateInWhateverWayYouPrefer(inputString);
DateFormat outputFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS");
String outputString = outputFormat.format(inputDate);
You might want to have a look at joda time, which is a little easier to use than the java native date tools, and provides many common date patterns pre-built.
In response to comments, more detail:
To do this using Joda time, you need two DateTimeFormatters - one for your input format to parse your input and one for your output format to print your output. Your input format is an ISO standard format, so Joda time's ISODateTimeFormat class has a static method with a parser for it already: dateHourMinuteSecondMillis. Your output format isn't one they have a pre-built formatter for, so you'll have to make one yourself using DateTimeFormat. I think DateTimeFormat.forPattern("mm/dd/yyyy kk:mm:ss.SSS"); should do the trick. Once you have your two formatters, call the parseDateTime() method on the input format and the print method on the output format to get your result, as a string.
Putting it together should look something like this (warning, untested):
DateTimeFormatter input = ISODateTimeFormat.dateHourMinuteSecondMillis();
DateTimeFormatter output = DateTimeFormat.forPattern("mm/dd/yyyy kk:mm:ss.SSS");
String outputFormat = output.print( input.parseDate(inputFormat) );
Hope this Helps:
public String getSystemTimeInBelowFormat() {
String timestamp = new SimpleDateFormat("yyyy-mm-dd 'T' HH:MM:SS.mmm-HH:SS").format(new Date());
return timestamp;
}
Use DateFormat. (Sorry, but the brevity of the question does not warrant a longer or more detailed answer.)

Categories

Resources