I have date strings in various formats like Oct 10 11:05:03 or 12/12/2016 4:30 etc
If I do
// some code...
getDate("Oct 10 11:05:03", "MMM d HH:mm:ss");
// some code ...
The date gets parsed, but I am getting the year as 1970 (since the year is not specified in the string.) But I want the year as current year if year is not specidied. Same applies for all fields.
here is my getDate function:
public Date getDate(dateStr, pattern) {
SimpleDateFormat parser = new SimpleDateFormat(pattern);
Date date = parser.parse(myDate);
return date;
}
can anybody tell me how to do that inside getDate function (because I want a generic solution)?
Thanks in advance!
If you do not know the format in advance, you should list the actual formats you are expecting and then try to parse them. If one fails, try the next one.
Here is an example of how to fill in the default.
You'll end up with something like this:
DateTimeFormatter f = new DateTimeFormatterBuilder()
.appendPattern("ddMM")
.parseDefaulting(YEAR, currentYear)
.toFormatter();
LocalDate date = LocalDate.parse("yourstring", f);
Or even better, the abovementioned formatter class supports optional elements. Wrap the year specifier in square brackets and the element will be optional. You can then supply a default with parseDefaulting.
Here is an example:
String s1 = "Oct 5 11:05:03";
String s2 = "Oct 5 1996 13:51:56"; // Year supplied
String format = "MMM d [uuuu ]HH:mm:ss";
DateTimeFormatter f = new DateTimeFormatterBuilder()
.appendPattern(format)
.parseDefaulting(ChronoField.YEAR, Year.now().getValue())
.toFormatter(Locale.US);
System.out.println(LocalDate.parse(s1, f));
System.out.println(LocalDate.parse(s2, f));
Note: Dates and times are not easy. You should take into consideration that date interpreting is often locale-dependant and this sometimes leads to ambiguity. For example, the date string "05/12/2018" means the 12th of May, 2018 when you are American, but in some European areas it means the 5th of December 2018. You need to be aware of that.
One option would be to concatenate the current year onto the incoming date string, and then parse:
String ts = "Oct 10 11:05:03";
int currYear = Calendar.getInstance().get(Calendar.YEAR);
ts = String.valueOf(currYear) + " " + ts;
Date date = getDate(ts, "yyyy MMM d HH:mm:ss");
System.out.println(date);
Wed Oct 10 11:05:03 CEST 2018
Demo
Note that we could have used StringBuilder above, but the purpose of brevity of code, I used raw string concatenations instead. I also fixed a few typos in your helper method getDate().
Related
I have a time stamp like this(form a json response) :
"/Date(1479974400000-0800)/"
I'm trying this function to convert time stamp into date:
public String getDate() {
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(time);
String date = DateFormat.format("dd-MM-yyyy", cal).toString();
return date;
}
How to convert this Timestamp into Date format?
Parse directly into an OffsetDateTime
Java can directly parse your string into an OffsetDateTime. Use this formatter:
private static final DateTimeFormatter JSON_TIMESTAMP_FORMATTER
= new DateTimeFormatterBuilder()
.appendLiteral("/Date(")
.appendValue(ChronoField.INSTANT_SECONDS, 1, 19, SignStyle.NEVER)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.appendOffset("+HHMM", "Z")
.appendLiteral(")/")
.toFormatter();
Then just do:
String time = "/Date(1479974400000-0800)/";
OffsetDateTime odt = OffsetDateTime.parse(time, JSON_TIMESTAMP_FORMATTER);
System.out.println(odt);
Output is:
2016-11-24T00:00-08:00
In your string 1479974400000 is a count of milliseconds since the epoch of Jan 1, 1970 at 00:00 UTC, and -0800 is an offset of -8 hours 0 minutes from UTC (corresponding for example to Pacific Standard Time). To parse the milliseconds we need to parse the seconds since the epoch (all digits except the last three) and then the millisecond of second (the last three digits). By specifying the width of the milliseconds field as 3 Java does this. For it to work it requires that the number is at least 4 digits and not negative, that is not within the first 999 milliseconds after the epoch or earlier. This is also why I specify in the formatter that the seconds must not be signed.
I specified Z for offset zero, I don’t know if you may ever receive this. An offset of +0000 for zero can still be parsed too.
Original answer: parse the milliseconds and the offset separately and combine
First I want to make sure the timestamp I have really lives up to the format I expect. I want to make sure if one day it doesn’t, I don’t just pretend and the user will get incorrect results without knowing they are incorrect. So for parsing the timestamp string, since I didn’t find a date-time format that would accept milliseconds since the epoch, I used a regular expression:
String time = "/Date(1479974400000-0800)/";
Pattern pat = Pattern.compile("/Date\\((\\d+)([+-]\\d{4})\\)/");
Matcher m = pat.matcher(time);
if (m.matches()) {
Instant i = Instant.ofEpochMilli(Long.parseLong(m.group(1)));
System.out.println(i);
}
This prints:
2016-11-24T08:00:00Z
If you want an old-fashioned java.util.Date:
System.out.println(Date.from(i));
On my computer it prints
Thu Nov 24 09:00:00 CET 2016
This will depend on your time zone.
It is not clear to me whether you need to use the zone offset and for what purpose. You may retrieve it from the matcher like this:
ZoneOffset zo = ZoneOffset.of(m.group(2));
System.out.println(zo);
This prints:
-08:00
The zone offset can be used with other time classes, like for instance OffsetDateTime. For example:
OffsetDateTime odt = OffsetDateTime.ofInstant(i, zo);
System.out.println(odt);
I hesitate to mention this, though, because I cannot know whether it is what you need. In any case, it prints:
2016-11-24T00:00-08:00
If by date you mean Date instance, then you can do this:
new Date(Long.parseLong("\/Date(1479974400000-0800)\/".substring(7, 20)));
I assume this info in holding the String representing an Epoch and a TimeZone
"/Date(1479974400000-0800)/"
you need to get rid off the all the not necessary parts and keeping only the
1479974400000-0800
then the epoch is 1479974400000 and I guess the Timezone is 0800
then do:
String[] allTimeInfo = "1310928623-0800".split("-");
DateFormat timeZoneFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
timeZoneFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));
Date time = new java.util.Date(Long.parseLong(allTimeInfo[0]));
System.out.println(time);
System.out.println(timeZoneFormat.format(time));
The solution works
for me is like this:
String str = obj.getString("eventdate").replaceAll("\\D+", "");
String upToNCharacters = str.substring(0, Math.min(str.length(), 13));
DateFormat timeZoneFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
timeZoneFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
Date time = new java.util.Date(Long.parseLong(upToNCharacters));
// System.out.println(time);
model.setDate(String.valueOf(timeZoneFormat.format(time)));
Use time variable where you want
This question already has answers here:
Java program to get the current date without timestamp
(17 answers)
Closed 6 years ago.
I want to create a Date object without a TimeZone (eg : 2007-06-21). Is this possible?
When I use the following method it prints like Thu Jun 21 00:00:00 GMT 2007
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
TimeZone timeZone = TimeZone.getTimeZone("GMT");
timeZone.setDefault(timeZone);
sdf.setTimeZone(timeZone);
Date pickUpDate = sdf.parse("2007-06-21");
System.out.println(pickUpDate);
If you want to format a date, you need to use DateFormat or something similar. A Date is just an instant in time - the number of milliseconds since the Unix epoch. It doesn't have any idea of time zone, calendar system or format. The toString() method always uses the system local time zone, and always formats it in a default way. From the documentation:
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
So it's behaving exactly as documented.
You've already got a DateFormat with the right format, so you just need to call format on it:
System.out.println("pickUpDate" + sdf.format(pickUpDate));
Of course it doesn't make much sense in your sample, given that you've only just parsed it - but presumably you'd normally be passing the date around first.
Note that if this is for interaction with a database, it would be better not to pass it as a string at all. Keep the value in a "native" representation for as much of the time as possible, and use something like PreparedStatement.setDate to pass it to the database.
As an aside, if you can possibly change to use Joda Time or the new date/time API in Java 8 (java.time.*) you'll have a much smoother time of it with anything date/time-related. The Date/Calendar API is truly dreadful.
This is the toString() of the java.util.Date
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == gcal.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
So, if you will pass a Date and try to print it this will be printed out all the time.
Code:
Date date = new Date();
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date));
Date : Fri Apr 29 04:53:16 GMT 2016
Sample Output : 2016-04-29
Imports required :
import java.util.Date; //for new Date()
import java.text.SimpleDateFormat; // for the format change
System.out.println("pickUpDate " + sdf.format(pickUpDate));
You can use the above code to get formatted Date as String
Use this Code:
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
Date pickUpDate =sdf.parse("2007-06-21");
System.out.println("pickUpDate "+sdf.format(pickUpDate));
Hope it'll help you.
String your_format_date=sdf.format(pickUpDate);
System.out.println("pick Up Date " + your_format_date);
Date isn't a date. It's a timestamp. That's some impressive API design, isn't it?
The type you need is now java.time.LocalDate, added in Java 8.
If you can't use Java 8, you can use ThreeTen, a backport for Java 7.
This question already has answers here:
How to parse case-insensitive strings with JSR-310 DateTimeFormatter?
(3 answers)
Closed 6 years ago.
Been trying for 4 hours to figure this out.
:This works
String date = "Jul-01-2014 09:10:12";
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));
:This will not
String date = "JUL-01-2014 09:10:12";
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));
Only difference being the month all capitalized. Proper case of Jul works. Neither JUL or jul will work. I also tried pattern of 'LLL' with no luck. What am I missing??
Well apparently I needed to spend 5 hours on this.
While writing an extension to provide a workaround I discovered this.
String date = "01-JUL-2014 09:10:12";
DateTimeFormatterBuilder fmb = new DateTimeFormatterBuilder();
fmb.parseCaseInsensitive();
fmb.append(DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss"));
LocalDateTime dt = LocalDateTime.parse(date, fmb.toFormatter());
Works great for all case styles.
It doesn't look like that is supported by the official API.
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
The only option for month-of-year is there, and it does not explicitly mention any format supporting three capital letter months.
It's not terribly difficult to convert it back into a format that Java can respect though; it involves a wee bit of finagling the date and putting it back into a single String, though.
The solution below isn't as elegant or as clean as using a third party, but the added benefit is that one doesn't have to rely on the third party library for this code at all.
public String transformToNormalizedDateFormat(final String input) {
String[] components = input.split("-");
String month = components[0];
if(month.length() > 3) {
throw new IllegalArgumentException("Was not a date in \"MMM\" format: " + month);
}
// Only capitalize the first letter.
final StringBuilder builder = new StringBuilder();
builder.append(month.substring(0, 1).toUpperCase())
.append(month.substring(1).toLowerCase())
.append("-");
final StringJoiner stringJoiner = new StringJoiner("-");
Arrays.stream(components, 1, components.length).forEach(stringJoiner::add);
builder.append(stringJoiner.toString());
return builder.toString();
}
Try using DateTimeFormatterBuilder and making parser case-insensitive. Don't forget to specify locale. Otherwise month abbreviation might not be parsed by MMM in default locale:
DateTimeFormatter format = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-yyyy")
.toFormatter(Locale.ENGLISH);
LocalDate.parse("03-jun-2015", format);
M by definition takes July; Jul; 07. You might want to try (solution being a little ugly):
date = Character.toUpperCase(date.charAt(0)) + date.substring(1).toLowerCase();
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));
Or you can try using WordUtils from apache-commons for capitalize.
I have to compute something based on the Calendar's date, but I am receiving the complete Gregorian Calendar's String value.
Eg i/p received {may be - "new GregorianCalendar().toString()"} as String :- java.util.GregorianCalendar[time=1410521241348,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=8,WEEK_OF_YEAR=37,WEEK_OF_MONTH=2,DAY_OF_MONTH=12,DAY_OF_YEAR=255,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=27,SECOND=21,MILLISECOND=348,ZONE_OFFSET=0,DST_OFFSET=3600000]
I want to extract the Calendar's date value to process further computation.
You could find the time in the input string and convert it to a Gregorian Calendar. Then you would have to set its timezone as specified in the ZoneInfo field. Something like this might work:
String calendarAsString="java.util.GregorianCalendar[time=1410521241348,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Europe/London\",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=8,WEEK_OF_YEAR=37,WEEK_OF_MONTH=2,DAY_OF_MONTH=12,DAY_OF_YEAR=255,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=27,SECOND=21,MILLISECOND=348,ZONE_OFFSET=0,DST_OFFSET=3600000]";
int timeStart=calendarAsString.indexOf("time=")+5;
int timeEnd=calendarAsString.indexOf(',');
String timeStr=calendarAsString.substring(timeStart, timeEnd);
long timeInMillis=Long.parseLong(timeStr);
int timezoneIdStart=calendarAsString.indexOf("\"")+1;
int timezoneIdEnd=calendarAsString.indexOf("\",");
String timeZoneStr=calendarAsString.substring(timezoneIdStart, timezoneIdEnd);
System.out.println("time="+timeInMillis+" zone="+timeZoneStr);
Calendar calendar=Calendar.getInstance(TimeZone.getTimeZone(timeZoneStr));
calendar.setTimeInMillis(timeInMillis);
System.out.println(calendarAsString);
System.out.println(calendar);
or you can use a regular expression to do it, instead
String regex="time=([0-9]*),.*ZoneInfo\\[id=\"([^\"]*)\"";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(calendarAsString);
matcher.find();
timeStr=matcher.group(1);
timeInMillis=Long.parseLong(timeStr);
timeZoneStr=matcher.group(2);
System.out.println("time="+timeInMillis+" zone="+timeZoneStr);
calendar=Calendar.getInstance(TimeZone.getTimeZone(timeZoneStr));
calendar.setTimeInMillis(timeInMillis);
System.out.println(calendar);
Note: if you just want the calendar's Date value, you can construct it from the timeInMillis, without having to reconstruct the whole GregorianCalendar object (and without having to find the timezone if you don't want to).
Date date=new Date(timeInMillis);
Other answers are too complicated or wrong. The following will give you the milliseconds since the epoch, which is a universal timestamp that you can easily convert to most time representation classes, including Calendar or Date:
Pattern gregorianPattern = Pattern.compile("^java.util.GregorianCalendar\\[time=(\\d+).*");
Matcher matcher = gregorianPattern.matcher(param);
if(matcher.matches()) {
return Long.parseLong(matcher.group(1));
}
GregorianCalendar g=new GregorianCalendar(1975, 5, 7);
Date d=g.getTime();
System.out.println(g.toString());
SimpleDateFormat formatter=new SimpleDateFormat("yyyy MM dd");
System.out.println(formatter.format(d));
This is way to grab date from GregorianCalendar. i wish this will help to you
Adding more to this, you can retrieve any information you want using the format. It's just a matter of providing the correct format.
Ex:
Adding z or Z provides you with the timezone information
"yyyy MM dd z" - 2014 10 12 PDT
"yyyy MM dd Z" - 2014 10 12 -0700
Adding a 'T' would result in something like this:
"yyyy-MM-dd'T'HH:mm:ss.sssZ" - 2014-10-12T14:23:51.890+0530
In this HH represents hours in 24 hour format mm minutes ss seconds sss milliseconds.
This question already has answers here:
Java program to get the current date without timestamp
(17 answers)
Closed 6 years ago.
I want to create a Date object without a TimeZone (eg : 2007-06-21). Is this possible?
When I use the following method it prints like Thu Jun 21 00:00:00 GMT 2007
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
TimeZone timeZone = TimeZone.getTimeZone("GMT");
timeZone.setDefault(timeZone);
sdf.setTimeZone(timeZone);
Date pickUpDate = sdf.parse("2007-06-21");
System.out.println(pickUpDate);
If you want to format a date, you need to use DateFormat or something similar. A Date is just an instant in time - the number of milliseconds since the Unix epoch. It doesn't have any idea of time zone, calendar system or format. The toString() method always uses the system local time zone, and always formats it in a default way. From the documentation:
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
So it's behaving exactly as documented.
You've already got a DateFormat with the right format, so you just need to call format on it:
System.out.println("pickUpDate" + sdf.format(pickUpDate));
Of course it doesn't make much sense in your sample, given that you've only just parsed it - but presumably you'd normally be passing the date around first.
Note that if this is for interaction with a database, it would be better not to pass it as a string at all. Keep the value in a "native" representation for as much of the time as possible, and use something like PreparedStatement.setDate to pass it to the database.
As an aside, if you can possibly change to use Joda Time or the new date/time API in Java 8 (java.time.*) you'll have a much smoother time of it with anything date/time-related. The Date/Calendar API is truly dreadful.
This is the toString() of the java.util.Date
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == gcal.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
So, if you will pass a Date and try to print it this will be printed out all the time.
Code:
Date date = new Date();
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date));
Date : Fri Apr 29 04:53:16 GMT 2016
Sample Output : 2016-04-29
Imports required :
import java.util.Date; //for new Date()
import java.text.SimpleDateFormat; // for the format change
System.out.println("pickUpDate " + sdf.format(pickUpDate));
You can use the above code to get formatted Date as String
Use this Code:
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
Date pickUpDate =sdf.parse("2007-06-21");
System.out.println("pickUpDate "+sdf.format(pickUpDate));
Hope it'll help you.
String your_format_date=sdf.format(pickUpDate);
System.out.println("pick Up Date " + your_format_date);
Date isn't a date. It's a timestamp. That's some impressive API design, isn't it?
The type you need is now java.time.LocalDate, added in Java 8.
If you can't use Java 8, you can use ThreeTen, a backport for Java 7.