Number of seconds in "HH:MM:SS" - java

What's the best way to get the number of seconds in a string representation like "hh:mm:ss"?
Obviously Integer.parseInt(s.substring(...)) * 3600 + Integer.parseInt(s.substring(...)) * 60 + Integer.parseInt(s.substring(...)) works.
But I don't want to test that, and reinvent the wheal, I expect there is a way to use DateTimeFormat or other classes from standard libraries.
Thanks!

Based on pakores solution:
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date reference = dateFormat.parse("00:00:00");
Date date = dateFormat.parse(string);
long seconds = (date.getTime() - reference.getTime()) / 1000L;
reference is used to compensate for different timezones and there is no problem with daylight saving time because SimpleDateFormat does NOT use the actual date, it return the Epoc date (January 1st, 1970 = no DST).
Simplifying (not much):
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = dateFormat.parse("01:00:10");
long seconds = date.getTime() / 1000L;
but I would still have a look at Joda-Time...

An original way:
The Calendar version (updated with the suggestions in the comments):
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = dateFormat.parse(string);
//Here you can do manually date.getHours()*3600+date.getMinutes*60+date.getSeconds();
//It's deprecated to use Date class though.
//Here it goes an original way to do it.
Calendar time = new GregorianCalendar();
time.setTime(date);
time.setTimeZone(TimeZone.getTimeZone("UTC"));
time.set(Calendar.YEAR,1970); //Epoc year
time.set(Calendar.MONTH,Calendar.JANUARY); //Epoc month
time.set(Calendar.DAY_OF_MONTH,1); //Epoc day of month
long seconds = time.getTimeInMillis()/1000L;
Disclaimer: I've done it by heart, just looking at the documentation, so maybe there is a typo or two.

joda-time is 1 options. infact i prefer that library for all date manipulations. I was going thru the java 5 javadoc and found this enum class which is simple and useful for you. java.util.concurrent.TimeUnit. look at the convert(...) methods. http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/java/util/concurrent/TimeUnit.html

Here is the link to a Java example of time formatting.
http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/i18n/format/simpleDateFormat.html

Related

Convert Excel timestamp to java.sql.date

I am extracting a timestamp out of Excel (2010):
It is displayed as "10.06.2015 14:24". The "internal representation" of excel is "42165.6". Last one is outputted from Excel.
So, for now, I want to parse this timestamp into a Java program like this:
double input = 42165.6;
// long myLong = ???
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm");
System.out.println(sdf.format(new java.sql.Date(myLong)));
How can I do this in line 2?!
Many thanks for your help!!!
Kind regards
Excel stores dates as the number of days since January 1900. This makes it awkward to convert into a Java date (milliseconds since 1 Jan 1970). If you cannot export it in a readable format, you'll need to create a Java Calendar, set it to 1 Jan 1900, and add the number of days.
Here it is:
double excelDate = 42165.6;
int days = (int) excelDate; //number of days
int seconds = (int) ((excelDate-days) * 86400); //number of seconds in .6 days
//create calendar set to 01-Jan-1900
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1900);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
//Add days and seconds to get required date/time
cal.add(Calendar.DATE, days-1);
cal.add(Calendar.SECOND, seconds);
//cal.getTime() returns a java.util.Date, print it out...
System.out.println(cal.getTime());
NOTE
A java.sql.Date can be created from a java.util.Date as follows:
java.util.Date utilDate = ....
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
The fastest way to get from the excel notation to a java.sql.Date is:
double excelInput = 42165.6;
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm");
System.out.println("---> "
+ sdf.format(new java.sql.Date(
(long) ((excelInput - 25569) * 86400 * 1000))));
Excel stores a date since 01-01-1900, java.sql.date since 01-01-1970. There are exactly 25569 days difference between both dates. The constructor of java.sql.Date wants the milliseconds (!) since 01-01-1970, so with "* 86400" we get the seconds and then with (* 1000) the milliseconds.
That's it! ;)
Putting 42165.6 in excel and formatting to a date gives the correct date 6/10/15 14:24.
For me the answers by mrbela and NickJ both gave incorrect answers to the question of 42165.6, 06/10/2015 09:23 and 06/12/2015 03:25. This seems to be true of most of the examples I've tried.
The solution that worked for me was to use Apache POI, which is a java API for Microsoft Documents. This question is very similar and had the pointers that led me to poi.
Here is a working code example.
double input = 42165.6;
Date date = DateUtil.getJavaDate(input);
System.out.println(new SimpleDateFormat("dd.MM.yyyy HH:mm").format(javaDate));
which outputs the correct 06/10/2015 14:24

Incrementing date by 18years in java

1.I want to set the setMaxSelectableDate=18years in JDateChooser so i provided it the date by incrementing milliseconds but how should i increment it by 18years.
2.Incrementing by 18years the calculation comes out to be 365*18*24*60*60*1000=56764800000 which gives me error integer number to large.
Date max=new Date();
Date oth1=new Date(max.getTime() + (365*18*24*60*60*1000)); //days*hours*minutes*seconds*milliseconds
SimpleDateFormat maxdateFormatter1 = new SimpleDateFormat("MMM d,yyyy hh:mm:ss a");
String maxdate=maxdateFormatter1.format(oth1);
DateChooser_V1.setMaxSelectableDate(new java.util.Date(maxdate));
Let java.util.Calendar do this work for you:
Calendar c = Calendar.getInstance();
c.setTime(oldDate);
c.add(Calendar.YEAR, 18);
Date newDate = c.getTime();
Which takes care of leap years, historical GMT offset changes, historical Daylight Saving Time schedule changes etc.
You need to use a long. You can achieve this by adding an L to your number:
365L* ...
With JodaTime
DateTime in18Years = new DateTime( ).plusYears( 18 );
Here is how to convert to java.util.Date
Date in18Years = new DateTime( ).plusYears( 18 ).toDate( );
You cannot willy-nilly add seconds (or millseconds) and expect calendar calculations to come out right. Basically it takes some extra effort to account for all of those leap-years, leap seconds, and daylight savings shifts.
Until Java 1.8 comes out, use java.util.Calendar instead of java.util.Date, there are really good reasons that java.util.Date has practically everything in it deprecated. While it looks good in the beginning, with enough use you will find it often "just doesn't work (tm)".
GregorianCalendar now = new GregorianCalendar();
now.add(Calendar.YEAR, 18);
And that's assuming that you didn't overflow Integer.MAX_INT.
I would use a Calendar object to achieve this:
Calendar cal = Calendar.getInstance();
Date dt = new Date();
...
// Set the date value
...
cal.setTime(dt);
cal.add(Calendar.YEAR, +18);
dt = cal.getTime();
Hope this helps you

Java Date/Calendar oddness

I have a bit of (Java) that I where I am trying to simply subtract 7 days from the current date. It seemed to me like Calendar.add(..) should be the method to use (and what previous questions here seem to say), so that's what I tried:
SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
System.out.println("ReportUtil.getDefaultReportStartDate cal: "+cal.toString() );
System.out.println("PRE ReportUtil.getDefaultReportStartDate: "+df.format(cal.getTime()) );
cal.add(Calendar.DATE, -7);
System.out.println("POST ReportUtil.getDefaultReportStartDate: "+df.format(cal.getTime()) );
That looks ok to me but you'll see from the output below the month field seems to go a bit... sideways! The day of the month/date seems to change correctly, but what is going on with the month?!
ReportUtil.getDefaultReportStartDate cal: java.util.GregorianCalendar[time=1330098699960,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GB-Eire",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=GB-Eire,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=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2012,MONTH=1,WEEK_OF_YEAR=8,WEEK_OF_MONTH=4,DAY_OF_MONTH=24,DAY_OF_YEAR=55,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=51,SECOND=39,MILLISECOND=960,ZONE_OFFSET=0,DST_OFFSET=0]
PRE ReportUtil.getDefaultReportStartDate: 24-51-2012
POST ReportUtil.getDefaultReportStartDate: 17-51-2012
SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
You get a strange month value because mm means minutes. Try:
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy");
You can consult the whole list of the format symbols here: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
mm is the format string for Minute. You want MM
Your result seems to be correct.
The month is "1" in both dates of your first log line, which means February.
The "-mm-" in your SimpleDateFormat means minute and not month, thus the odd month of "51"

How can I get Date in MM/DD/YY format from Timestamp

I want to get the Date in MM/DD/YY format from a timestamp.
I have used the below method but it does not gives proper output
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(Long.parseLong(1306249409));
Log.d("Date--",""+cal.DAY_OF_MONTH);
Log.d("Month--",""+cal.MONTH);
Log.d("Year--",""+cal.YEAR);
But its gives the output like below
Date--5
Month--2
Year--1
The correct date is 24 May 2010 for Timestamp - 1306249409
Note - Timestamp is received by a webservice which is used in my application.
Better Approach
Simply Use SimpleDateFormat
new SimpleDateFormat("MM/dd/yyyy").format(new Date(timeStampMillisInLong));
Mistake in your Approach
DAY_OF_MONTH ,MONTH, .. etc are just constant int value used by Calendar class
internally
You can get the date represented by cal by cal.get(Calendar.DATE)
Use the SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String time = sdf.format(date);
What's wrong:
Calendar.DAY_OF_MONTH, Calendar.MONTH etc are static constants used to access those particular fields. (They will remain constant, no matter what setTimeInMillis you provide.)
How to solve it:
To get those particular fields you can use the .get(int field)-method, like this:
Log.d("Month--",""+cal.get(Calendar.MONTH));
As others have pointed out there are more convenient methods for formatting a date for logging. You could use for instance the SimpleDateFormat, or, as I usually do when logging, a format-string and String.format(formatStr, Calendar.getInstance()).
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
String s = formatter.format(date);
System.out.println(s);
TimeZone utc = TimeZone.getTimeZone("UTC"); // avoiding local time zone overhead
final Calendar cal = new GregorianCalendar(utc);
// always use GregorianCalendar explicitly if you don't want be suprised with
// Japanese Imperial Calendar or something
cal.setTimeInMillis(1306249409L*1000); // input need to be in miliseconds
Log.d("Date--",""+cal.get(Calendar.DAY_OF_MONTH));
Log.d("Month--",""+cal.get(Calendar.MONTH) + 1); // it starts from zero, add 1
Log.d("Year--",""+cal.get(Calendar.YEAR));
Java uses the number of milliseconds since 1st January 1970 to represent times. If you compute the time represented by 1306249409 milliseconds, you'll discover that it's only 362 days, so your assumptions are wrong.
Moreover, cal.DAY_OF_MONTH holds a constant. Use cal.get(Calendar.DAY_OF_MONTH) to get the day of month (same for other parts of the date).
use String.format which is able to convert long (milliseconds) to date/time string in different formats:
String str;
long time = 1306249409 * 1000L; // milliseconds
str = String.format("%1$tm/%1$td/%1$ty", time); // 05/24/11
str = String.format("%tF", time); // 2011-05-24 (ISO 8601)
str = String.format("Date--%td", time); // Date--24
str = String.format("Month--%tm", time); // Month--05
str = String.format("Year--%ty", time); // Year--11
documentation: format string.

Java: convert a time from today to a timestamp

I am using Java 6, and I have a time from the current date as a string, like this: 14:21:16, and I need to convert this to a Timestamp object to store in a database.
However there seems to be no good way to get a Timestamp from this. Timestamp.valueOf(String) is quite close, but requires a date. Is there a good way to make a Timestamp object from such a string?
How about this:
final String str = "14:21:16";
final Timestamp timestamp =
Timestamp.valueOf(
new SimpleDateFormat("yyyy-MM-dd ")
.format(new Date()) // get the current date as String
.concat(str) // and append the time
);
System.out.println(timestamp);
Output:
2011-03-02 14:21:16.0
Personally, I'd use Joda Time to parse the time to a LocalTime, and add that to today's LocalDate to get a LocalDateTime, then convert that into an Instant using whatever time zone you're interested in. (Or use LocalTime.toDateTimeToday(DateTimeZone).)
Then just create a time stamp using the Timestamp(long) constructor.
There are plenty of other approaches (e.g. using SimpleDateFormat instead of parsing with Joda Time, if you really want...) but ultimately you're likely to want the Timestamp(long) constructor in the end. (The benefit of using Joda Time here is that it's obvious what's being represented at each stage - you're not trying to treat a "time only" as a "date and time" or vice versa.)
Best I can come up with using standard API is not that pretty:
// Get today's date and time.
Calendar c1 = Calendar.getInstance();
c1.setTime(new Date());
// Get the required time of day, copy year, month, day.
Calendar c2 = Calendar.getInstance();
c2.setTime(java.sql.Time.valueOf("14:21:16"));
c2.set(Calendar.YEAR, c1.get(Calendar.YEAR));
c2.set(Calendar.MONTH, c1.get(Calendar.MONTH));
c2.set(Calendar.DAY_OF_MONTH, c1.get(Calendar.DAY_OF_MONTH));
// Construct required java.sql.Timestamp object.
Timestamp time = new Timestamp(c2.getTimeInMillis());
Let's see what we've done.
System.out.println(time);
Note that java.sql.Time.valueOf accepts a string of the form "HH:MM:SS" as you require. Other formats would require use of SimpleDateFormat.
Use org.apache.commons.lang.time.DateUtils:
Date today = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date time = df.parse("14:21:16");
Timestamp time = new Timestamp(today.getTime() + time.getTime());
Have a given day (say, unix epoch?) to serve as the day. When you use it, only use the time parameters that you care about, ignoring the day.
Another option would be java.sql.Time
http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Time.htm
String str = "14:21:16";
DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = formatter.parse(str);
Timestamp timestamp = new Timestamp(date.getTime());

Categories