I want to convert a String (with reserved characters) to Date in Java
I have a string with some reserved characters in it. I am getting it from some source. Also I get the format of it from the same source. I tried to convert that string to a date but I was unable to.
The date I get:
{ts '2021-03-24 12:52:38.933'}
The format I get:
'{ts' ''yyyy-MM-dd HH:mm:ss{.SSS}[Z]'''}'
I tried with the sample code snippet but since {} are reserved characters and also ts is an invalid character for parsing, I am unable to parse it. Please help with how I can solve this.
Obviously I can do some string manipulation and convert it to a format I want but I don't want to do that.
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
SimpleDateFormat sdf = new SimpleDateFormat("{ts' ''yyyy-MM-dd HH:mm:ss{.SSS}[Z]'''}", Locale.ENGLISH);
try {
Date date = sdf.parse(dateInString);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
You need to escape ' with another '.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
SimpleDateFormat parser = new SimpleDateFormat("'{ts '''yyyy-MM-dd HH:mm:ss.SSS'''}'", Locale.ENGLISH);
Date date = parser.parse(dateInString);
System.out.println(date);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println(formatter.format(date));
}
}
Output:
Wed Mar 24 12:52:38 GMT 2021
2021-03-24T12:52:38.933
ONLINE DEMO
Note that the java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String dateInString = "{ts '2021-03-24 12:52:38.933'}";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("'{ts '''yyyy-MM-dd HH:mm:ss.SSS'''}'", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(dateInString, parser);
System.out.println(ldt);
}
}
Output:
2021-03-24T12:52:38.933
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Related
I wan to convert the string d (date in UTC format) to String in UTC format with 'T' and increment 5 mins to time. Below is the code
public static void main (String args[]) throws ParseException
{
String d="2021-08-27 06:25:00.716241+00:00";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSXXX");
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date actualDate = format.parse(d);
String a=format1.format(actualDate);
System.out.println(a);
}
I get output as 2021-08-27T12:06:56 but I need String 'a' as 2021-08-27T06:25:00 and then add 5 mins to it and make it 2021-08-27T06:30:00
Please help
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String d = "2021-08-27 06:25:00.716241+00:00";
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s.SSSSSSXXX", Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse(d, dtfInput);
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
String str = odt.format(dtfOutput);
System.out.println(str);
// Add 5 minutes to it
odt = odt.plusMinutes(5);
str = odt.format(dtfOutput);
System.out.println(str);
}
}
Output:
2021-08-27T06:25:00
2021-08-27T06:30:00
ONLINE DEMO
Learn more about the modern Date-Time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I want to verify if date (java.util.Date) is correct
like 2021/02/31 does not exist
DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
dateFormat.setLenient(false);
try{
dateFormat.parse(dateFormat.format(date));
} catch(ParseException e) {
return false;
}
return true;
I recommend you to do it using the modern date-time API*
Use DateTimeFormatter#withResolverStyle(ResolverStyle.STRICT) to resolve a date strictly.
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDate = "2021/02/31";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu/MM/dd", Locale.ENGLISH)
.withResolverStyle(ResolverStyle.STRICT);
try {
LocalDate date = LocalDate.parse(strDate, dtf);
// ...
} catch (DateTimeException e) {
System.out.println(e.getMessage());
}
}
}
Output:
Text '2021/02/31' could not be parsed: Invalid date 'FEBRUARY 31'
Learn more about the modern date-time API from Trail: Date Time.
Also, note that yyyy-mm-dd is not a correct format for your date string which has / instead of - and m is used for a minute, not a month for which you have to use M.
The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
First of all your date format uses mm which represents minutes, for months it needs to be MM.
Secondly I am not sure what you meant to do with dateFormat.parse(dateFormat.format(date));. The inner part (dateFormat.format(Date)) should be used to convert a date to a string, and the outer part (dateFormat.parse(String)) is to convert a string to a date. So this seems to be a bit of a pointless operation.
I think what you meant was something like this, which should check the validity of date properly:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
try{
dateFormat.parse(dateFormat.format("2021-02-31"));
} catch(ParseException e) {
return false;
}
return true;
Having said this, using the new Java Date-Time APIs is always a better approach, so I would defer to the answer from #ArvindKumarAvinash for a more future-proof solution.
i have date coming from server & is in the format = "2013-01-20T16:48:43" my application support Both Arabic & English Locale. But when i change the locale to Arabic the date is not parsing its giving me parse exception. till now what i have written is
private static Date parseJsonDate(final String string) throws Exception
{
final String change_Locale = Locale.getDefault().getISO3Language();
if (change_Locale.equalsIgnoreCase("ara"))
{
System.out.println(":: Date :::" + string);
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", new Locale("ar"));
System.out.println("new date " + format.parse(string));
return format.parse(string);
Do not parse your date into the Arabic it will give you error alwayz besides try as below by setting the Locale ENGLISH only.
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
Your error seems to be due to some bug in the older version of Java.
Note that in March 2014, the modern Date-Time API supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time, the modern date-time API.
The java.time API has a specialised type, LocalDateTime to represent an object that has just date and time units, and no timezone information.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
class Main {
public static void main(String[] args) throws ParseException {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", new Locale("ar"));
LocalDateTime ldt = LocalDateTime.parse("2013-01-20T16:48:43", parser);
System.out.println(ldt);
// Alternatively, as suggested by Basil Bourque
parser = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withLocale(new Locale("ar"));
System.out.println(LocalDateTime.parse("2013-01-20T16:48:43", parser));
// Your parser
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", new Locale("ar"));
System.out.println(format.parse("2013-01-20T16:48:43"));
}
}
Output:
2013-01-20T16:48:43
2013-01-20T16:48:43
Sun Jan 20 16:48:43 GMT 2013
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
I will be giving input date time for a timezone and the timezone for the input date time and we want the relevant DateTime in the expected timezone.
And here is my method.
convertToTimezone("03/08/2010 20:19:00 PM","Asia/Shanghai","US/Central");
The above time is the time in Asia/Shanghai. We would like to know what is the corresponding time in US/Central.
It's working fine but I am getting a 1-hour difference from the actual time.
Can I know where I am going wrong?
Here is the code:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateUtil {
private static String format_date = "MM/dd/yyyy HH:mm:ss a";
public static void main(String a[]) {
try {
String sourceTimezone = "Asia/Shanghai";
String destTimezone = "US/Central";
String outputExpectedTimezone = convertToTimezone("03/08/2010 20:19:00 PM", sourceTimezone, destTimezone);
System.out.println("outputExpectedTimezone :" + outputExpectedTimezone);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static String convertToTimezone(String inputDate, String inputDateTimezone, String destinationDateTimezone)
throws Exception {
String outputDate = null;
SimpleDateFormat format = new SimpleDateFormat(format_date);
format.setTimeZone(TimeZone.getTimeZone(inputDateTimezone));
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(inputDateTimezone));
calendar.setTime(format.parse(inputDate));
calendar.add(Calendar.MILLISECOND, -(calendar.getTimeZone().getRawOffset()));
calendar.add(Calendar.MILLISECOND, -calendar.getTimeZone().getDSTSavings());
calendar.add(Calendar.MILLISECOND, TimeZone.getTimeZone(destinationDateTimezone).getRawOffset());
outputDate = format.format(calendar.getTime());
return outputDate;
}
}
You shouldn't be adding anything to the calendar - that represents a specific instant in time. In fact, you don't need a calendar at all.
Instead, have two different formats, one for each time zone:
public static String convertToTimezone(String inputDate,
String inputDateTimezone,
String destinationDateTimezone)
throws Exception
{
SimpleDateFormat parser = new SimpleDateFormat(format_date);
parser.setTimeZone(TimeZone.getTimeZone(inputDateTimezone));
Date date = parser.parse(inputDate);
SimpleDateFormat formatter = new SimpleDateFormat(format_date);
formatter.setTimeZone(TimeZone.getTimeZone(outputDateTimezone));
return formatter.format(date);
}
As an aside, I'd thoroughly recommend using Joda Time instead of the built-in date/time API.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
Since your input Date-Time does not have timezone information, parse it into a LocalDateTime
Attach the timezone of the input Date-Time with it to get a ZonedDateTime
Use the ZonedDateTime#withZoneSameInstant to convert this ZonedDateTime to the target ZonedDateTime
Return the formatted target ZonedDateTime.
Demo:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(convertToTimezone("03/08/2010 20:19:00 PM", "Asia/Shanghai", "US/Central"));
System.out.println(convertToTimezone("03/08/2010 20:19:00 PM", "Asia/Shanghai", "America/Mexico_City"));
}
static String convertToTimezone(String inputDate, String inputDateTimezone, String destinationDateTimezone) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(inputDate, dtf);
ZonedDateTime zdtInput = ldt.atZone(ZoneId.of(inputDateTimezone));
ZonedDateTime zdtDestination = zdtInput.withZoneSameInstant(ZoneId.of(destinationDateTimezone));
return zdtDestination.format(dtf);
}
}
Output:
03/08/2010 06:19:00 AM
03/08/2010 06:19:00 AM
ONLINE DEMO
Note: Avoid using the deprecated ID, US/Central. Use the standard ID, America/Mexico_City where Mexico City is the largest city in this timezone.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I have time stamp as 29-NOV-11 06.05.41.831000000 AM
Using SimpleDateFormat , i cannot really extract millisecond (.831000000) ....831 is millisecond (and i don't know why those 000000. But thats coming from different source. No control on that.)
The extra digits are nano-second. You can't include these in SimpleDateFormat or the standard libraries. The simplest thing to do in you case is to remove them before parsing the date/time.
java.time
Parse your date-time string into the OffsetDateTime using the timezone offset of UTC and convert the result into an Instant.
You can convert the Instant into milliseconds using Instant#toEpochMilli.
Demo:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d-MMM-uu h.m.s.n a")
.toFormatter(Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
OffsetDateTime odt = OffsetDateTime.parse("29-NOV-11 06.05.41.831000000 AM", dtf);
Instant instant = odt.toInstant();
long millis = instant.toEpochMilli();
System.out.println(millis);
}
}
Output:
1322546741831
Learn more about the the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
A working solution... A fairly strict regex for this is quite long-winded as you see.
String input = "29-NOV-11 06.05.41.831000000 AM";
input = input
.replaceFirst(
"(\\d+-\\w+-\\d+\\s\\d+\\.\\d+\\.\\d+\\.\\d{3})\\d{6}(\\s(\\w+))",
"$1$2");
try {
SimpleDateFormat sdf = new SimpleDateFormat(
"dd-MMM-yy HH.mm.ss.SSS aa");
Date date = sdf.parse(input);
System.out.println(sdf.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
You could just use substr if the strings are always fixed width and you consider regex a bit of overkill.
input = input.substring(0, 22) + input.substring(28, 31);
If the timestamp is represented by a string you could use a regular expression to parse out the extra zeroes.