I want to display the date of a trip. In the application several trips are listed, each has a long value with the currentTimeMillis of its generation. I want to turn this long number into a date but the output is always something around 1970... Is System.currentTimeMillis() the right way to store the time of the trip generation?
Date date = new Date(trip.getStartTime()); // 195342322
SimpleDateFormat test = new SimpleDateFormat("yyyy-MM-dd");
startTime.setText(String.valueOf(test.format(date)));
-> Output of startTime: 1970-01-01
Try to use Calendar for simple formatting
We don't know how trip.getStartTime() is implemented, however it returns a wrong value. 195342322 is Wed, 10 Mar 1976 21:45:22 GMT (you can check it online)
Since the only non-deprecated Date constructor accepts a long argument, I guess you used that. It's better to store the date(time) in a database-friendly way, such as ISO 8601. Note that if you store it on the client in a SQLite database, SQLite doesn't have a time type, and you have to use a text field for that.
Once you switch to the text representation for serialization, you will be able to get back a Date by using SimpleDateFormat.parse()
use something like this:
Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(trip.getStartTime());
Date date =calendar.getTime ();
as shown here .
Related
I'm reading information from a file (.csv) that will be inserted to a database after validation and approval from the end user. The text file is read, validated and its information loaded to a List containing forms which are used to check if the data already exist in database.
The problem arises when parsing the String to Date. The SimpleDateFormat.parse() method returns an unexpected date format even when the pattern for SimpleDateFormat is "yyyy-MM-dd".
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
Parsing the loaded values to the travel object:
travel.setDate( dateFormat.parse( form.getTravelDate() ));
In debugger the form shows the date as:
"2012-12-12"
It is read as intended. However when parsed becomes:
Wed Dec 12 00:00:00 CST 2012
I've spent the whole day trying to solve this but I'm out of ideas at this point. Afaik the pattern is alright and I've tried adding a locale to no avail.
Edit: the problem is when I need to insert the values to the database using Hibernate. The not desired format also ends up showing in the Database.
The data is show in a .jsp page using
HttpServletRequest("table",travelList);
The date format I don't need shows here, when in the past this issue never happened. At last the information is sent to the database where the problem persists.
No, it "becomes" a java.util.Date value. If you're then converting it back to a string by calling Date.toString(), you should consult the Date.toString() documentation for what to expect.
The value stored in the Date is just a point in time - the number of milliseconds since the Unix epoch. There's no format in there, no time zone etc. It also doesn't know that it was only a date value rather than a date and time (the naming of Date is one of the many unfortunate aspects of the API).
It's crucial that you mentally separate "the result of the parse operation" from "the string value that is used to represent that result if I call toString"".
I'd also advise you to set the time zone on your SimpleDateFormat to UTC when parsing a date - that way you know that you can't possibly have any ambiguous or skipped times leading to hard-to-predict behaviour. (Of course, you then need to know that you'll have parsed the date to "the start of the UTC date" and handle it appropriately elsewhere.)
You need to use the formatter when printing the Date as well.
dateFormat.format( travel.getDate() );
When your parse the String using a DateFormat, you get a complete Date object with the time units missing in the string initialized to zero. In your example, that's hours, minutes and seconds.
By default, if you do not use a formatter, Date's default string representation (provided by its toString() method) gets printed.
Parsing doesn't mean it format, it simply parse it as text to a java.util.Date object. See parse method in documentation.
You need to use the format method.
dateFormat.format(travel.getDate())
See documentation for more details.
if form.getTravelDate() is returning String then First Parse the Date from String
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
Date parsedDate=dateFormat.parse(form.getTravelDate());
// Here parsedDate is in form Wed Dec 12 00:00:00 CST 2012
Now Format the Date using the Same SImpleDateFormat to get the desired output
System.out.println(dateFormat.format(parsedDate));
Your Desired Output
2012-12-12
Update
Assuming data Type of Columns in which we insert this data in Database is of Date Type not varchar then use the below statement
travel.setDate(dateFormat.format(parsedDate));
As I understand parse method returns Date. Below is the parse method syntax.
public Date parse(String source)
throws ParseException
So, you need to parse the string date and store into a Date variable. Then format the Date variable using SimpleDateFormat.
//getTravelDate is "2012-12-12"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
Date dtObj=new Date();
dtObj=dateFormat.parse(form.getTravelDate()); //Store in date variable
System.out.println(dateFormat.format(dtObj)); // Now format the date object
The final output will be 2012-12-12. Hope it will help you.
I am working on some time stuff on Android. I get the time from a TimePicker and I want to store it in the database. I want to store time in a 12-hour format.
I also need to do some calculations on that time. If I store it as a String, it will involve a lot of coding to do calculations on that String.
Is there a better solution?
Any help would be appreciated. Thanks in advance.
In my androidapp i am storing datetime as long in java and database.
(Unix Time, number of seconds since 1970-01-01. as #hawaii.five-0 stated)
These numbers can easily be compared for earlier/later dates but are hard to read for a human when looking into raw database.
For displaying dates these long numbers are converted back to java Date with new Date(longValue).
Best practice is to store time as Unix timestamps:
Easy calculations (you can just add and subtract time in seconds, so to add an hour you add 60*60 = 3600 seconds)
Easy formatting: the Java Date and DateFormat classes can easily handle Unix timestamps.
Example of 12 hour formatting:
public String getDateFormatted(Date datum) {
DateFormat dfm = new SimpleDateFormat("MM/dd/yyyy K:m a"); //example: 05/23/2012 11:34 PM
return dfm.format(datum);
}
Unfortunately sqlite does not support Date format... Take a look at sqlite affinity.
So you have to store it in text or numeric format.. And apply your computations after retriving it from the database..
How can I convert time in unix timestamp to normal time?
Your question is vague and ambiguous. I'll leave the timezone ambiguity away.
How can I convert time in unix timestamp to normal time?
I suspect that you're somehow obtaining a long or maybe a String value from the DB instead of a Date. In JDBC, you would normally like to use the appropriate methods to obtain the DB-specific datatypes. The MySQL TIMESTAMP datatype can be obtained by ResultSet#getTimestamp() which gives you a java.sql.Timestamp which in turn is a subclass of java.util.Date.
In a nut, the following should do:
Date date = resultSet.getTimestamp("columnname");
To format it further in a human readable format whenever you're going to present it to the enduser, use SimpleDateFormat. Click the link, it contains an overview of all patterns. Here's an example:
String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
To do all the other way round, use respectively SimpleDateFormat#parse() and PreparedStatement#setTimestamp().
Unix timestamp is seconds since "epoch". Java's currentTimeMillis are milliseconds since "epoch". You can get a Java Date object with a simple multiplication like this:
Date dateFromUnixTime = new Date( 1000l * unixTime) ;
From there, you can format it using the normal date formatting tools in Java.
I have a db, that stores dates in OleDateTime format, in GMT timezone. I've implemented a class, extending Date in java to represent that in classic date format. But my class is locale-dependent (I'm in GMT+2). Therefore, it converts the date in the db as date - 2 hours. How do I make it convert the date correctly? I want my class to be locale-independent, always using GMT timezone. Actually, the question is:
class MyOleDateTime extends Date {
static {
Locale.setDefault(WhatGoesHere?)
}
// ... some constructors
// ... some methods
}
Well, it's better to use the Calendar object like suggested in other answers. However, if you really want to set global timezone, you can use TimeZone.setDefault(TimeZone.getTimeZone("UTC")); early in your application code. There is also user.timezone Java system property.
Also (just fun to know), it appears that the only country actually living by GMT/UTC time (without daylight saving changes) is Liberia.
In fact, Date objects per se are always locale- and timezone-independent. Its getTime() method will always return the number of milliseconds passed since January 1, 1970 00:00:00 (not counting leap seconds) in UTC. But if you want to get something else than milliseconds, you have to use Calendar, which is timezone-dependent. But it is the right way to go. You don't use that deprecated methods in Date class, do you?
As Michael Borgwardt has already said, the Java Date object does not know anything about timezones. It's just a wrapper for a number of milliseconds since 01-01-1970 00:00:00 UTC.
You start dealing with timezones only when you for example convert the Date object to a String using a DateFormat. You set the timezone on the DateFormat to specify in which timezone you want to see the Date.
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String text = df.format(date); // text will contain date represented in UTC
A Date is locale-independent, always using GMT timezone. It's just a wrapper around a millisecond timestamp in GMT (more correctly: UTC).
The only things in Date that are timezone dependant are the deprecated methods like getDay() - that's why they're deprecated. Those use the default time zone. The correct thing to do is to avoid using those deprecated methods - not to set the default timezone to UTC! That could cause problems elsewhere, and you can't prevent other parts of the code from setting the default timezone to something else.
Use a Calendar object:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
locale);
Here's a snippet I used to calculate the GMT offset from the Calendar instance and format it. I appreciate all the help I've gotten from this site, its nice to contribute. I hope this helps someone somewhere. Enjoy.
Calendar calInst = Calendar.getInstance();
//calculate the offset to keep calendar instance GMT
int gmtOffsetMilli = calInst.get(Calendar.ZONE_OFFSET);
long gmtOffsetHr = TimeUnit.HOURS.convert(gmtOffsetMilli, TimeUnit.MILLISECONDS);
calInst = Calendar.getInstance(TimeZone.getTimeZone("GMT " + gmtOffsetHr));
I need to store the timezone an email was sent from. Which is the best way to extract it from the email's 'Date:' header (an RFC822 date)? And what is the recommended format to store it in the database (I'm using hibernate)?
I recommend you use Mime4J.
The library is designed for parsing all kinds of email crap.
For parsing dates you would use its DateTimeParser.
int zone = new DateTimeParser(new StringReader("Fri, 27 Jul 2012 09:13:15 -0400")).zone();
After that I usually convert the datetimes to Joda's DateTime. Don't use SimpleDateFormatter as will not cover all the cases for RFC822.
Below will get you the Joda TimeZone (from the int zone above) which is superior to Java's TZ.
// Stupid hack in case the zone is not in [-+]zzzz format
final int hours;
final int minutes;
if (zone > 24 || zone < -24 ) {
hours = zone / 100;
minutes = minutes = Math.abs(zone % 100);
}
else {
hours = zone;
minutes = 0;
}
DateTimeZone.forOffsetHoursMinutes(hours, minutes);
Now the only issue is that the Time Zone you will get always be a numeric time zone which may still not be the correct time zone of the user sending the email (assuming the mail app sent the users TZ and not just UTC).
For example -0400 is not EDT (ie America/New_York) because it does not take Daylight savings into account.
Probably easiest to parse with JodaTime as it supports ISO8601 see Date and Time Parsing and Formatting in Java with Joda Time.
DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
System.out.println(parser2.parseDateTime(your_date_string));
Times must always be stored in UTC (GMT) with a timezone - i.e. after parsing convert from the timezone to GMT and remove daylight savings offset and save the original timezone.
You must store the date with the timezone after converting to UTC.
If you remove or don't handle the timezone it will cause problems when dealing with data that has come from a different timezone.
Extract the data from the header using some sort of substring or regular expression. Parse the date with a SimpleDateFormatter to create a Date object.
The timezone in the email will not show in which timezone it was send. Some programs use ever UTC or GMT. Of course the time zone is part of the date time value and must also be parse.
Why do you want know it.
- Do you want normalize the timestamp? Then use a DateFormat for parsing it.
- Do you want detect the timezome of the user that send the email? This will not correctly work.
It looks like you already mentioned this in one of your comments, but I think it's your best answer. The JavaMail library contains RFC822 Date header parsing code in javax.mail.internet.MailDateFormat. Unfortunately it doesn't expose the TimeZone parsing directly, so you will need to copy the necessary code directly from javax.mail.internet.MailDateParser, but it's worth taking advantage of the careful work already done.
As for storing it, the parser will give you the date as an offset, so you should be able to store it just fine as an int (letting Hibernate translate that to your database for you).