What will be the regular expression for following Timestamp format
YYYY-MM-DD HH:mm:ss.S
YYYY-MM-DD HH:mm:ss.S AM/PM
YYYY-MM-DD HH:mm:ss.S AM/PM Z
YYYY-MM-DD HH:mm:ss.S Z
Where
Y: year,
M: Month,
D: Date,
H: hour,
m: minute,
s: second,
S: Milisecond 3 digit only,
Z: Time zone.
I am getting timestamp format in string format so want to validate it.
How to check above regular expression in GWT?
Just something simple as only describing the pattern like this:
^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}(?: [AP]M)?(?: [+-]\d{4})?$
as any tentative of real date validation with a regex sounds inherently wrong.
I got the uppercase Z as RFC822 timezone, regex needs changes to comply to TZDs or general textual time zones.
Apart from Datejs which relays on js to check a date-string, Gwt comes with DateTimeFormat to parse date-string and format dates with support for locales. It raises a IllegalArgumentException in the case the parsed string doesn't match the expected format .
String dateStr = "2011-04-21 20:37:36.999 -0800";
String fmt = "yyyy-MM-dd HH:mm:ss.S Z"; // your 4th case: YYYY-MM-DD HH:mm:ss.S Z
DateTimeFormat format = DateTimeFormat.getFormat(fmt);
try {
Date date = format.parse(dateStr);
System.out.println("Validated: " + date);
} catch (IllegalArgumentException e) {
System.out.println("Validation error: " + e.getMessage());
}
dateStr = "2011-04-21 08:37:36.999 PM -0800"; // your 3rd case YYYY-MM-DD HH:mm:ss.S AM/PM Z
fmt = "yyyy-MM-dd hh:mm:ss.S a Z";
format = DateTimeFormat.getFormat(fmt);
try {
Date date = format.parse(dateStr);
System.out.println("Validated: " + date);
} catch (IllegalArgumentException e) {
System.out.println("Validation error: " + e.getMessage());
}
You dont say whether the format string is fixed or it can be provided in runtime before performing the validation. So in the second case you need to use replace to change 'Y' by 'y', and 'AM/PM' to 'a' which are the symbols used in DateTimeFormat
I would say use Datejs
Otherwise you will need to do a lot of coding, and regex is not the best for verifying timestamps and if it is valid.
Datejs will check the date validity, and from that you will receive a Date object or null (if it is invalid!).
Date.parse("2013-02-02 12:01:01.000", "yyyy-MM-dd HH:mm:ss.u");
For more information see:
Datejs API documentation
Datejs Format spec
Related
I'm trying to parse only time ignoring weekday from the string with the following format: "Monday 5AM"
Here is my code:
String dateTxt = "Monday 5AM";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ha");
LocalTime lt = LocalTime.parse(dateTxt, formatter);
It throws an exception:
java.time.format.DateTimeParseException: Text 'Saturday 1AM' could not be parsed
How to parse only time from that string?
You need to change the format to
"EEEE ha"
I would also recommend to set the Locale so you have the right language and that it supports AM/PM
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE ha", Locale.ENGLISH);
I see the question has been edited now, if you only want the time you can extract or format that from the parse LocalTime object
LocalTime lt = LocalTime.parse(dateTxt, formatter);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("h a", Locale.ENGLISH);
System.out.println(lt);
System.out.println(lt.format(formatter2));
05:00
5 AM
If we want to ignore the day then we can use following patterns:
[ optional section start
] optional section end
This has different behavior while parsing and formatting. Note: the same pattern has been used for parsing and formatting in following code.
String dateTxt = "Monday 5AM";
//for parsing day of week is ignored
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[EEEE ]ha", Locale.ENGLISH);
LocalTime lt = LocalTime.parse(dateTxt, formatter);
System.out.println(lt + " - parsed local time ");
//in case of formatting if data is not available
//then the field won't be in output
System.out.println(lt.format(formatter) + " -local time with optnal day in format.");
//the day is available so it will be there in output
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.format(formatter) + " -local date time with optnal day in format");
Output:
05:00 - parsed local time
5AM -local time with optnal day in format.
Saturday 2PM -local date time with optnal day in format
For formatting if the data is not available then that won't be in output.
If you are only interested in the time, why not just extract that part from dateTxt and parse that part only.
String dateTxt = "Monday 5AM";
DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
DateTimeFormatter fmtr = dtfb.appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)
.appendText(ChronoField.AMPM_OF_DAY, TextStyle.SHORT)
.toFormatter(Locale.ENGLISH);
String timeTxt = dateTxt.split(" ")[1];
System.out.println(LocalTime.parse(timeTxt, fmtr));
try{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
Date parsedDate = dateFormat.parse(tm);
timestamp = new java.sql.Timestamp(parsedDate.getTime());
}
catch (Exception pe) {
System.out.println("unexpected exception");
System.out.println(pe);
pe.printStackTrace();
}
Console shows "unexpected error"(which is in my catch block). I am trying to convert "tm" which is client-side input date into a timestamp. The value of tm is like "YYYY-MM-DD HH:MM: SS"(String). But the console keeps on showing Unparseable date. I am new to Java.
java.time
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String tm = "2019-02-09 07:35:54";
LocalDateTime dateTime = LocalDateTime.parse(tm, formatter);
System.out.println(dateTime);
This produces the following output:
2019-02-09T07:35:54
I discourage the use of SimpleDateFormat, Date and Timestamp. Those classes are poorly designed and long outdated, the first in particular notoriously troublesome. Instead I am using java.time, the modern Java date and time API.
JDBC 4.2+
If you thought you needed a Timestamp for your database, you probably don’t. Assuming your JDBC driver is up to JDBC 4.2 you can directly give it the LocalDateTime object we just produced. For example like:
PreparedStatement ps = yourConnection.prepareStatement(
"insert into your_table(your_timestamp_col) values (?);");
ps.setObject(1, dateTime);
What went wrong in your code?
There are two errors in your format pattern string, yyyy-MM-dd hh:mm:ss.SSS:
Assuming that the hours in the user input are hour of day from 00 through 23, you need uppercase HH to parse them, as LppEdd already said in a comment (lowercase hh is for hour within AM or PM from 01 through 12 and of course requires that an AM or PM marker is present).
Since the user input doesn’t include fraction of second, you should not have .SSS in the format pattern (this is probably what caused your exception).
Link
Oracle tutorial: Date Time explaining how to use java.time.
Maybe you want to try this out
String tm = "2014-01-01 00:00:00";
String frontEndFormat = "yyyy-MM-dd HH:mm:ss";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(frontEndFormat);
LocalDateTime localDateTime = LocalDateTime.parse(tm, formatter);
Timestamp timestamp = Timestamp.valueOf(localDateTime);
//prints 2014-01-01 00:00:00.0
System.out.println(timestamp);
You can notice the upper case HH used for hours and the lower case mm used for minutes.
I'm trying to use Java 8 to re-format today's date but I'm getting the following error:
java.time.format.DateTimeParseException: Text '09-OCT-2017' could not be parsed:
Unable to obtain LocalDate from TemporalAccessor:
{WeekBasedYear[WeekFields[SUNDAY,1]]=2017, MonthOfYear=10, DayOfYear=9},ISO of type java.time.format.Parsed
Code:
public static String formatDate(String inputDate, String inputDateFormat, String returnDateFormat){
try {
DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern(inputDateFormat).toFormatter(Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(inputDate, inputFormatter);
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(returnDateFormat);
String formattedString = localDate.format(outputFormatter);
return formattedString;
} catch (DateTimeParseException dtpe) {
log.error("A DateTimeParseException exception occured parsing the inputDate : " + inputDate + " and converting it to a " + returnDateFormat + " format. Exception is : " + dtpe);
}
return null;
}
I previously tried using SimpleDateFormat, but the problem is my inputDateFormat format is always in uppercase DD-MMM-YYYY, which was giving me incorrect results, so I tried using parseCaseInsensitive() to ignore the case sensitivity.
In the comments you told that the input format is DD-MMM-YYYY. According to javadoc, uppercase DD is the day of year field, and YYYY is the week based year field (which might be different from the year field).
You need to change them to lowercase dd (day of month) and yyyy (year of era). The parseCaseInsensitive() only takes care of the text fields - in this case, the month name (numbers are not affected by the case sensitivity - just because the month is in uppercase, it doesn't mean that the numbers patterns should also be).
The rest of the code is correct. Example (changing the format to yyyyMMdd):
String inputDate = "09-OCT-2017";
DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
// use "dd" for day of month and "yyyy" for year
.appendPattern("dd-MMM-yyyy")
.toFormatter(Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(inputDate, inputFormatter);
// use "dd" for day of month and "yyyy" for year
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
String formattedString = localDate.format(outputFormatter);
System.out.println(formattedString); // 20171009
The output of the code above is:
20171009
Regarding your other comment about not having control over the input pattern, one alternative is to manually replace the letters to their lowercase version:
String pattern = "DD-MMM-YYYY";
DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
// replace DD and YYYY with the lowercase versions
.appendPattern(pattern.replace("DD", "dd").replaceAll("YYYY", "yyyy"))
.toFormatter(Locale.ENGLISH);
// do the same for output format if needed
I don't think it needs a complex-replace-everything-in-one-step regex. Just calling the replace method multiple times can do the trick (unless you have really complex patterns that would require lots of different and complex calls to replace, but with only the cases you provided, that'll be enough).
I hope I got you right.
Formatting a String to LocalDate is acutally pretty simple. Your date format is that here right 09-Oct-2017?
Now you just need use the split command to divide that into a day, month and year:
String[] tempStr = inputDate.split("-");
int year = Integer.parseInt(tempStr[2]);
int month = Integer.parseInt(tempStr[1]);
int day = Integer.parseInt(tempStr[0]);
After that it´s pretty easy to get that to LocalDate:
LocalDate ld = LocalDate.of(year, month, day);
I hope that helps.
This question already has answers here:
Java string to date conversion
(17 answers)
Closed 5 years ago.
I am trying to convert dates of the format
07/Mar/2004:16:56:39 -0800
to a date object. I'm not sure what that format's name even is but its used in tomcat access logs. Can someone please help me out?
SimpleDateFormat f = new SimpleDateFormat("dd-MMM-yyyy:HH:mm:ss");
Date d = f.parse("07/Mar/2004:16:56:39 -0800"); // Throws exception.
System.out.println(d.getTime());
The format string should match the input. In particular, the separator must match.
Also, your format string is missing the time zone part to match against the -0800.
Since your input uses English month name, you should explicitly specify that, e.g. using Locale.US.
SimpleDateFormat f = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z", Locale.US);
Date d = f.parse("07/Mar/2004:16:56:39 -0800");
System.out.println(d);
Since I'm in Eastern time zone, that prints:
Sun Mar 07 19:56:39 EST 2004
You should however use the new java.time classes instead.
Since the input string has a time zone offset, that means you should parse the string to an OffsetDateTime, using a DateTimeFormatter:
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MMM/uuuu:HH:mm:ss Z", Locale.US);
OffsetDateTime dt = OffsetDateTime.parse("07/Mar/2004:16:56:39 -0800", f);
System.out.println(dt);
Output is:
2004-03-07T16:56:39-08:00
You need to add the time zone to your date format and change the format to your input string (/ instead of -):
SimpleDateFormat f = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z", Locale.US);
See the docs: https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
You have a typo in the line:
Date d = f.parse("07/Mar/2004:16:56:39 -0800");
The format for the date is "dd-MMM-yyyy:HH:mm:ss". You need to replace the "/" with "-". Additionally, you need to surround your parse function with a try-catch block as follows:
SimpleDateFormat f = new SimpleDateFormat("dd-MMM-yyyy:HH:mm:ss");
Date d;
try {
d = f.parse("07-Mar-2004:16:56:39");
System.out.println(d.getTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Check out this link to learn more about the SimpleDateFormat Class:
http://www.xyzws.com/javafaq/how-to-use-simpledateformat-class-formating-parsing-date-and-time/142
Is the formatter representation "yyyy-MM-dd HH:mm:ss.sss" is correct way to format the date.
Note that here I've used small 's'(instead of capital 'S') to indicate milliseconds which results wrong time.
If yes what is the difference between yyyy-MM-dd HH:mm:ss.sss and yyyy-MM-dd HH:mm:ss.SSS.
Why some are in small letters and some are in capital letters to indicate the date format.
Here is the sample code which shows the difference
SimpleDateFormat dateFormatLocal = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.SSS");
SimpleDateFormat dateFormatLocal1 = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
try {
Date d = dateFormatLocal.parse("2015-07-21 11:01:27.063");
Date d1 = dateFormatLocal1.parse("2015-07-21 11:01:27.063");
System.out
.println("------------- Sync Completed in Date -------------"
+ d.getTime());
System.out
.println("------------- Sync Completed in Date -------------"
+ d1.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
//OutPut is
//------------- Date in SSS -------------1437456687063
//------------- Date in sss -------------1437456723000
As you have discovered, the correct pattern for milliseconds is SSS, while sss represents seconds.
They are different capitalization because they represent different parts of the date/time.
In the same way that it would be incorrect to use "yy" four hours, it is incorrect to use "sss" for milliseconds.