I'm wondering if there is a static String or DateFormat anywhere in the standard Java library for formatting dates 'completely'. By completely, I mean the date and time including milliseconds and timezone, something along the lines of "dd MMM yyyy HH:mm:ss.SSS zzz". It's easy to just declare the string myself, but it would be nice if I didn't have to do that for every project I use that needs millisecond-precision date parsing. I have been unable to find one so far.
As an aside, I think it's a little silly that java.util.Date#toString() doesn't account for milliseconds when the class it represents does.
Edit - Unfortunately, it is not as simple as beginning the conversion over to DateTime usage, as that is not something that is in my control. I am the 2nd most junior developer on the project. I would love to use DateTime going forward, but without the support of my supervisor, I cannot.
Also for Java 8 Date Time Api you can use
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME);
for results like that
2017-03-27T20:46:03.852
Related
I'm scraping some data for a user, part of it is a date in a Unix Timestamp:
The user is living in London and wants to see the date for his specific time zone. As you can see, on GMT it is 6/21, on my time zone (Israel Time Zone) it's 6/22.
I used this snippet code to fix:
private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
txnDate = "1529618400000" //this is hardcoded, just for the example
txnDateValue = new Date(Long.valueOf(txnDate));
TimeZone london = TimeZone.getTimeZone("Europe/London");
sdf2.setTimeZone(london);
txnDate = sdf2.format(txnDateValue);
So that the date will be converted to the correct time zone (London in his case).
It still doesn't work for him - he claims that he sees the date in one day difference.
What could go wrong here?
What could go wrong here?
The Date obtained and stored in txnDateValue could have been read wrong, with bad time zone or bad format or whatever
The DateFormat built and stored in sdf2 could be badly made or badly used, with bad pattern or concurrent use or whatever.
Bottomline, you should design complete programs to test the input/output on your side and your partner's side, and if that's not enough to help you find the problem, you should show us this complete programs.
Code snippets are useless. We don't have problems, you do. If we use code snippets you provide, we won't have problems with them. You're the one who have problems with them. So, there is no sense showing anything but a complete program we can run as-is.
Modern version: use java.time
Instant txnDateValue = Instant.ofEpochMilli(Long.parseLong(txnDate));
ZoneId london = ZoneId.of("Europe/London");
txnDate = txnDateValue.atZone(london).format(DateTimeFormatter.ISO_LOCAL_DATE);
The above gives an Instant of 2018-06-21T22:00:00Z (where Z means UTC) and a txnDate of 2018-06-21. Like you own code it is not thread-safe if some other thread may manipulate txnDate or some other variable involved.
What went wrong in your code?
I cannot tell. Kumesana suggested a race condition, like concurrent use of your SimpleDateFormat, this is a possibility. Other possibilities are that your program isn’t working on the data you think or your user in London made a mistake. Apart from these conditions I believe that your program should produce 2018-06-21.
Link
Oracle tutorial: Date Time explaining how to use java.time including the classes Instant, ZoneId and DateTimeFormatter that I used in my code.
I'm using the following code to convert the time to local time. It was running 'on time' but today it jumped ahead by an hour.
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
Using "ET" instead of "EST" doesn't work.
How can I correct the converted time?
Thanks!
You only show the code that creates the SimpleDateFormat, so apparently you are sure the problem is in there?
Debugging date/time/timezone/daylight savings related problems can be very difficult because it is very hard to 'see' the actual date; when you inspect it the Date's toString method will do some timezone conversion of it's own (based on current locale). So I find it most easy to convert all input to UTC and then print it out in UTC locale.
Anyway, you say 'ET' does not work? I have little experience with it, but if you look at the docs for TimeZone you should be able to come up with an algortithm o print out all timezones installed on your system. If EST differs from ET (does it?) then this will never work. You need to figure out the names Java has assigned to the ET timezone and use those to create the date formatter.
The trick is to parse the input (which is in locale X) using a date formatter for locale X and then use the Date (which is always in UTC, so timezone-neutral so to say) in your calculations. Then only go back to timezone X or Y for output by using a date format with the correct locale again.
You might try using EDT.
I know that seems totally counter to what you are trying to do here, but you might have a double adjustment somewhere if it sees EST and tries to convert to EDT.
The fact that daylight savings just hit today really points to the TimeZone issue.
I'm having an hard time trying to parse date in the future, and I would apreciate some help!
Here's the thing, I'd like to add a parsed date to the current date (to have it in the future). The problem is that I can have many kind of date format, like :
dd
MM-dd
yyyy-MM-dd
So if the user set something like 5, the returned date will be (in our timelapse) 2011-11-05.
If he set 02-14, it will be 2012-02-14.
But suppose we are the 4th of november, and the user set 11-03, it will be 2012-11-03 and not 2011-11-03 since it's past.
I tried to play with Calendar, Date, SimpleFormat, but I cannot make it work.
My parsers (using SimpleDateFormat) are working though.
Could you help me archieve this? I'm not asking for a complete code, just something that would set me on the right track!
thanks! :)
Since you have fixed list of acceptable input date format, set the lenient field of dateFormat to false and check to see if one of them satisfy your work done or if exception is raised go for next pattern
dateFormat = new SimpleDateFormat(PATTERN_ONE);
dateFOrmat.setLenient(false);
dateFormat.parse(INPUT_STRING);
// if an exception is caughtm try with next pattern
I have had very good experience with jodatime - http://joda-time.sourceforge.net/. Checkout the Dateformatters in that.
It has a very extensive API and lets you do things like add and subtract dates - taking into account timezones and daylight saving etc.
I want to save a Date object to a readable string (for example 22/10/2009 21:13:14) that is also parsable back to a Date object.
I have tried many things and the best I could find was to use DateFormater for parsing and formating but it has a setback. When you format a date you lose seconds information. I tried to find if there is an option to format it and display the seconds (even better would be to the millisecond level since that's the resolution the Date object allows you to have) but I came up short.
Any ideas?
Take a look at java.text.SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
Date dt = new Date();
String S = sdf.format(dt); // formats to 09/23/2009 13:53:28.238
Date dt2 = sdf.parse(S); // parses back
SimpleDateFormat can format and parse a date based on a very simple pattern system that include second and even milliseconds.
Other answers are all good.
But when doing this kind of thing please pick a format that sorts properly when coded as a string.... "yyyy/MM/dd HH:mm:ss" is fine. It always astounds me when software engineers pick a date format which doesn't sort in the obvious, convenient way.
You'll save your fellow developers a lot of pain at some distant point in the future - think of it as good karma :-)
ISO 8601
Use ISO 8601 format.
It’s flexible, it includes seconds and fraction of second if there are any, but you may also leave them out if they are 0.
It’s standard, so more and more tools format and parse it. Great for serialization for storage or data interchange.
It goes like 2009-10-22T21:13:14, I should say it’s pretty human-readable (though the T in the middle that denotes the start of the time part may feel unusual at first).
The strings sort properly, as mikera requested in another answer, as long as the years are in the four-digit range from 1000 through 9999.
The classes of java.time, the modern Java date and time API, as well as those of Joda Time parse ISO 8601 as their default, that is, without any explicit formatter, and produce the same format from their toString methods.
A modest demonstration of using java.time:
LocalDateTime dateTime = LocalDateTime.of(2009, 10, 22, 21, 13, 14);
String readableString = dateTime.toString();
System.out.println(readableString);
LocalDateTime parsedBack = LocalDateTime.parse(readableString);
System.out.println(parsedBack);
This prints two identical lines:
2009-10-22T21:13:14
2009-10-22T21:13:14
The latter System.out.println() call implicitly calls toString() once more, so this shouldn’t surprise.
A little off-topic, but I always feel the need to remind people that DateFormat and SimpleDateFormat are not thread safe! The Sun documentation clearly states this, but I keep finding code out in the wild where people stick a SimpleDateFormat in a static ...
If you want to do it a little simpler, and be spared from making your own DateFormat that most other Answers involve, you can leverage the default format in java.time.Instant:
(new Date()).toInstant.toString();
I have a string that contains the representation of a date. It looks like:
Thu Nov 30 19:00:00 EST 2006
I'm trying to create a Date object using SimpleDateFormat and have 2 problems.
1.) I can't figure out the pattern to hard-code the solution into the SimpleDateFormat constructor
2.) I can't find a way I could parse the string using API to determine the pattern so I could reuse this for different patterns of date output
If anyone knows a solution using API or a custom solution I would greatly appreciate it.
The format to pass to SimpleDateFormat could be looked up at http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy")
As for your second question, I don't know of any Java library to figure out a date format and parse it without knowing in advance what the format is.
The POJava date parser org.pojava.datetime.DateTime is an immutable, and robust parser that supports multiple languages, time zones, and formats.
Best of all, the parser is heuristic and does not require a pre-existing “format” to work. You just pass it a date/date-time text string and get out a java.util.Date!
I'm not sure there's any easy way to parse a date and work out its pattern, but I would have thought that the pattern for the one you posted would be:
EEE MMM dd HH:mm:ss zzz yyyy
If you want to do anything other than parse or format a date there is not much out there for handling the patterns themselves. Sometime ago I was writing a Swing component for entering dates into a formatted text field. You supplied a pattern and it moved the text entry cursor through the elements of that pattern, only allowing valid values.
As part of that I wrote a DateFormatParser available here as part of the OpenHarmonise open source project.
Parsing a date into a pattern would be an extremely interesting problem to tackle. You would have to make certain assumptions (e.g. use of : in time not date) but you would face the eternal problems of 2 digit years and day/month or month/day arrangements.
It's worth knowing that the date format you have given is not an arbitrary one. It is the output of the built-in Date.toString() method (at least in the UK and US locales). Not coincidentally, it is also the format of the unix 'date' command (at least on linux, and I believe in other implementations too) - though to be pedantic, Date.toString() pads one-digit day numbers with a zero while unix date does not.
What this means is that you are likely to receive this input format when you output an unformatted date into a user-modifiable field (e.g. an HTML INPUT field) and receive it back unmodified. So just because input is coming in this format, doesn't mean the users will type in a thousand other arbitrary formats.
Of course, they still might. The way I handle date inputs in general is with a bunch of try/catch blocks, where I try it against one format, then another, then another. Our standard framework is now up to about 20 different formats by default. Of course it is still not perfect; I found someone the other day entering "03 Sept" as the date (a non-standard month abbreviation, and with no year) and we hadn't handled that scenario.
See Apache Commons' DateUtils. There's a parseDate method that takes your String and multiple patterns to try and spits out a Date instance.
As others have said, the pattern looks like it should be
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"
As for parsing an arbitrary format date, I'm not aware of any library which does this in Java. If you were keen to develop such a thing, I would start by looking at the perl str2time function.
I must say i find the other question very interesting. There is one serious problem though - parse this: 08/07/06! If you limit yourself on a subset of expected formats, you could probably solve problem by playing around with regexps, you could build up bunch of expected patterns, and then break Strings on spaces or whatever, and match part by part.
Are you just asking for the pattern for that given date? If so, I think this should do it:
"EEE MMM d HH:mm:ss z yyyy"
Or are you trying to take any formatted date, and infer the format, and parse it?
How about:
EEE MMM dd HH:mm:ss zzz yyyy
Just pass the string into the constructor of SimpleDateFormat. To use the object, just call the parse method passing in the string you want converted to a Date.
You could take a look at:
http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html
This isn't really the same, but you might want to look at something like JChronic, which can do natural language processing on dates. So, the input date could be something like "tomorrow", or "two weeks from next tuesday".
This may not help at all for your application, but then again, it might.