What is the best way to convert hours into the time.
Lets say 5 hours and current time is 9:17am
Now if I run the app the time should be 0417 (am)
Thanks
A sequence to do that based on current time:
Calendar cal = new GregorianCalendar();
cal.set( Calendar.HOUR_OF_DAY, 9 );
cal.set( Calendar.MINUTE, 17 );
cal.add( Calendar.HOUR_OF_DAY, -5 );
System.out.println( cal.getTime() );
You can create a new DateObject like this:
Date time5HoursBefore = new Date( System.currentTimeMillis() - 5 * 3600000 ); //3600000 is the number of milliseconds per hour
An alternative would be using Apache Commons' DateUtils:
Date time5HoursBefore = DateUtils.addHours(new Date(), -5);
Related
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy/MM/dd" ).withZone( timeZone );
DateTime dateTimeStart = formatter.parseDateTime("2012/01/01");
DateTime dateTimeStop = formatter.parseDateTime("2017/06/12");
Period period = new Period( dateTimeStart, dateTimeStop );
PeriodFormatter periodFormatter = PeriodFormat.getDefault();
String output = periodFormatter.print( period);
System.out.println(output);
Actual Output is: 5 years, 5 months, 1 week and 4 days
I want output (Recommended) : 5 years, 5 months, 11 days
If you read the manual...
Period period = new Period(dateTimeStart, dateTimeStop, PeriodType.forFields(
new DurationFieldType[]{
DurationFieldType.years(),
DurationFieldType.months(),
DurationFieldType.days(),
DurationFieldType.hours(),
DurationFieldType.minutes(),
DurationFieldType.seconds(),
DurationFieldType.millis(),
}));
I want to get the time of a day in milliseconds, I do not this day to have any specific date, just a time. I made something, thought it worked, but then went debugging and concluded that it doesn't work how I want it to.
I want to use this to check if the current time is between both my specified startTime and endTime.
long startTime = settings.getLong("startTime", 0);
long endTime = settings.getLong("endTime", 0);
if ((currentTime.getMillis() >= startTime)
&& (currentTime.getMillis() <= endTime)) {
//Do stuff here
}
How I am setting the time of the propeties startTime and endTime:
Calendar startTime = Calendar.getInstance();
startTime.set(Calendar.HOUR_OF_DAY, 16);
startTime.set(Calendar.MINUTE, 00);
editor.putLong("startTime",
startTime.getTimeInMillis());
Calendar endTime = Calendar.getInstance();
endTime.set(Calendar.HOUR_OF_DAY, 16);
endTime.set(Calendar.MINUTE, 00);
endTime.add(Calendar.HOUR_OF_DAY, 11);
editor.putLong("endTime",
endTime.getTimeInMillis());
editor.commit();
However this will mean that both startTimeand endTime will have this a specific date attached to it.
I hope I explained it well, any help is appreciated!
Avoid Milliseconds
No need to mess with milliseconds for your purpose. Using milliseconds for date-time is confusing and error-prone.
What you need is a decent date-time library rather than the notoriously troublesome bundled java.util.Date & .Calendar classes.
Joda-Time
If you are certain you want to ignore dates and ignore time zones, here's some example code using the LocalTime class offered by the third-party free-of-cost Joda-Time library.
LocalTime start = new LocalTime( 10, 0, 0 );
LocalTime stop = new LocalTime( 14, 30, 0 );
LocalTime target = LocalTime.now();
boolean isNowInSpan = !( ( target.isBefore( target ) ) | ( target.isAfter( stop ) ) );
Adjust that last line according to your business logic needs. You might want:
The beginning and ending are inclusive
The beginning and ending are exclusive
"Half-Open" where the beginning is inclusive and the ending is exclusive(usually best for date-time work)
Dump to console…
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "target: " + target );
System.out.println( "isNowInSpan: " + isNowInSpan );
When run…
start: 10:00:00.000
stop: 14:30:00.000
target: 23:49:37.779
isNowInSpan: false
Another Example
Time-of-day-only is not usually the right way to go. When new to date-time work, a naïve programmer may at first think that time-only simplifies things. On the contrary, this example shows how spinning around the clock creates complications. Using date+time+timeZone is usually the best approach in the long run.
LocalTime now = LocalTime.now();
LocalTime start = new LocalTime( 13, 0, 0, 0 );
LocalTime stop = start.plusHours( 11 );
System.out.println( "now: " + now );
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
if ( now.isAfter( start ) ) {
System.out.println( "After start" );
}
if ( now.isBefore( stop ) ) {
System.out.println( "Before stop" );
}
When run…
now: 14:00:32.496
start: 13:00:00.000
stop: 00:00:00.000
After start
java.time
Java 8 brings the new java.time package, inspired by Joda-Time, defined by JSR 310.
In java.time, you will find a LocalTime class similar to the one in Joda-Time.
A new approach with Java 8 onward.
int millisecondsOfDay = LocalTime.now().get(ChronoField.MILLI_OF_DAY);
Reference: https://o7planning.org/13669/java-localtime#a64448233
Take a look at the Java 8 Time API.
http://download.java.net/jdk8/docs/api/java/time/LocalTime.html#toNanoOfDay--
Time without Date is meaning less. In Java timestamp it's using the Unix UTC and the timestamp start 0 on 01/01/1970. So, you startTime/endTime.getTimeInMillis() tell you the time different from UTC. Which mean your midnight is your base and your endTime.getTimeInMillis() will be the offset.
Calendar cal = Calendar.getInstance();
// set to mid-night
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long midnight = cal.getTimeInMillis();
cal.set(Calendar.HOUR_OF_DAY, 16);
cal.set(Calendar.MINUTE, 00);
long startTime = cal.getTimeInMillis();
editor.putLong("startTime", (startTime - midnight));
cal.add(Calendar.HOUR_OF_DAY, 11);
long endTime = cal.getTimeInMillis();
editor.putLong("endTime", (endTime - midnight));
editor.commit();
java.time.LocalTime
I recommend that you use java.time, the modern Java date and time API, for your time work. Use a LocalTime object for time of day (it’s what it’s for).
LocalTime time = LocalTime.of(16, 0);
System.out.println(time);
Output:
16:00
If you cannot store a LocalTime object in your settings, convert to a string for human readability (a great advantage in debugging and support cases):
String timeString = time.toString();
LocalTime parsedBack = LocalTime.parse(timeString);
System.out.println(parsedBack);
16:00
To answer the question as asked, in case you need to, converting to milliseconds is straightforward (when you know how):
int milliOfDay = time.get(ChronoField.MILLI_OF_DAY);
System.out.println(milliOfDay);
57600000
The milliseconds too can be converted back to a LocalTime object:
LocalTime recreatedLocalTime
= LocalTime.MIN.with(ChronoField.MILLI_OF_DAY, milliOfDay);
System.out.println(recreatedLocalTime);
16:00
Link
Oracle tutorial: Date Time explaining how to use java.time.
In case what you need is to get how many milliseconds since the start of this day and you have now in milliseconds you can get the milliseconds you want as simple as this
val nowMilliSeconds = System.currentTimeMillis() % 86400000
Where 86400000 is the number of milliseconds in a day so you will just get the remainder
I'm getting some puzzling results with SimpleDateFormat and am hoping that someone can shed some light on the issue. The output:
Time = Mon Dec 27 00:00:00 PST 2010
2010-01 <--- THIS IS WHAT I DON'T UNDERSTAND
Start of week = Sun Dec 26 00:00:00 PST 2010
2010-01
End of Week = Sat Jan 01 23:59:59 PST 2011
2011-01
Should I be treating the last "week" of the year that extends to the next year as a special case? Or is this the correct way to interpret this? Obviously when attempting to organize week sequentially, the order is incorrect. Adjusting the initial values, Dec 25, 2005 is considered the 53rd week. I haven't looked at Joda yet to see if Joda produces similar results.
The relevant code:
private static Date getStartOfWeek( Date d ) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime( d );
calendar.set( Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() );
return calendar.getTime();
}
private static Date getEndOfWeek( Date d ) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime( d );
calendar.add( Calendar.WEEK_OF_YEAR, 1 );
calendar.set( Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() );
calendar.add( Calendar.MILLISECOND, -1 );
return calendar.getTime();
}
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set( 2010, Calendar.DECEMBER, 27 );
Date d = calendar.getTime();
Date start = getStartOfWeek( d );
Date end = getEndOfWeek( d );
SimpleDateFormat fmt = new SimpleDateFormat( "yyyy-ww" );
System.out.println( "Time = " + d );
System.out.println( fmt.format( d ) );
System.out.println( "Start of week = " + start );
System.out.println( fmt.format( start ) );
System.out.println( "End of Week = " + end );
System.out.println( fmt.format( end ) );
Background: I found this when using the crosstab (date grouped into week) in JasperReports.
EDIT: I am using JDK 1.6.0_25
EDIT: It seems that I will have to use Joda to get the correct result. TO get the week start/end, I ended up using: LocalDate.withDayOfWeek. To retrieve the year and week number, I used DateTime.getWeekyear and DateTime.getWeekOfWeekyear.
The bug is in your formatting code, not Java.
The surprising behavior is due to an esoteric rule in date notation. Note that ISO 8601 (rather confusingly) specifies different rules for year boundaries when using week numbers. In particular, 2010-12-27 is considered part of 2011 when using week numbers.
As a result, you should be using the "week year" YYYY rather than the usual year yyyy. (See http://download.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_year and the last example in http://download.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html.)
Also, the standard notation for dates uses an explicit 'W', so you should use new SimpleDateFormat( "YYYY-'W'ww" ) instead.
Edit: There's another problem. Java seems to default to the non-standard calendar.getMinimalDaysInFirstWeek() == 1, so you have to set
calendar.setMinimalDaysInFirstWeek( 4 );
in order to get the correct year.
Edit: From reading the Calendar javadocs, you might also need to set the starting day to Monday. Further, the YYYY format specifier seems to be new in Java 1.7. In light of this, unless you're willing to upgrade to a pre-release Java version, I recommend just using Joda Time.
From ISO Week
The first week of a year is the week that contains the first Thursday
of the year.
So the behavior has nothing to do with Java or Joda. This is how the "week of the year" is implemented worldwide (if they follow the ISO standard)
the standadr java Date & Time classes are not well designed and sometimes don't work as expected. use instead Joda Time
Yes, this looks to be a bug in Java, and not in the formatting code. If you print:
System.out.println("Week = " + calendar.get(Calendar.WEEK_OF_YEAR));
It also shows 1.
If you change your date to something not so close to the end of the year, eg:
calendar.set(2010, Calendar.NOVEMBER, 27);
Then the output looks right. BTW, I tested using Sun 1.6.0_25 64bit VM.
In Joda-Time, is there a way to get the date of the first day of the week(monday).
for instance i want to find out what date was this weeks monday based on todays current date 21/01/11
Cheers in advance.
edit: i also wish to find the date for the end of the week i.e sunday's date. cheers
Try LocalDate.withDayOfWeek:
LocalDate now = new LocalDate();
System.out.println(now.withDayOfWeek(DateTimeConstants.MONDAY)); //prints 2011-01-17
System.out.println(now.withDayOfWeek(DateTimeConstants.SUNDAY)); //prints 2011-01-23
LocalDate today = new LocalDate();
LocalDate weekStart = today.dayOfWeek().withMinimumValue();
LocalDate weekEnd = today.dayOfWeek().withMaximumValue();
Will give you the first and last days i.e Monday and sunday
Another option is to use roundFloorCopy. This looks like the following:
LocalDate startOfWeek = new LocalDate().weekOfWeekyear().roundFloorCopy();
For the last day of the standard week (Sunday) use roundCeilingCopy and minusDays…
LocalDate lastDateOfWeek = new LocalDate().weekOfWeekyear().roundCeilingCopy().minusDays( 1 );
Also works for DateTime. And works for end of week (exclusive).
DateTime dateTime = new DateTime();
DateTime startOfWeek = dateTime.weekOfWeekyear().roundFloorCopy();
DateTime endOfWeek = dateTime.weekOfWeekyear().roundCeilingCopy();
Dump to console…
System.out.println( "dateTime " + dateTime );
System.out.println( "startOfWeek " + startOfWeek );
System.out.println( "endOfWeek " + endOfWeek );
When run…
dateTime 2014-01-24T00:00:34.955-08:00
startOfWeek 2014-01-20T00:00:00.000-08:00
endOfWeek 2014-01-27T00:00:00.000-08:00
You can use the getDayOfWeek() method that gives you back 1 for Monday, 2 for Tue, .., 7 for Sunday in order to go back that many days and reach Monday:
import org.joda.time.DateTime;
public class JodaTest {
public static void main(String[] args) {
DateTime date = new DateTime();
System.out.println(date);
//2011-01-21T15:06:18.713Z
System.out.println(date.minusDays(date.getDayOfWeek()-1));
//2011-01-17T15:06:18.713Z
}
}
See the section "Querying DateTimes" of the Joda-Time user guide.
Here is the general algorithm I would follow:
find the day-of-week of the target date (Jan 21 2011 as you mentioned)
determine how many days ahead of Monday this is
Subtract the value of #2 from the target date using dateTime.minusDays(n)
Today is Tuesday, February 9, 2010 and when I print the date I get the wrong date:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date today = formatter.parse(String.format("%04d-%02d-%02d",
Calendar.getInstance().get(Calendar.YEAR),
Calendar.getInstance().get(Calendar.MONTH),
Calendar.getInstance().get(Calendar.DAY_OF_MONTH)));
System.out.println("Today is " + today.toString());
The print line results in: "Today is Sat Jan 09 00:00:00 CST 2010"
It most certainly is not Saturday Jan 09, it's Tuesday Feb 09. I'm assuming I'm doing something wrong, so can anybody let me know what's wrong here? Do I have to manually set the day of week?
Update
Note: I don't want to initialize today with new Date() because I want the hours, minutes, seconds and milliseconds initialized to 0. This is necessary so I can compare a user input date with today: if the user inputs today's date and I use the formatter to construct a Date object, then if I initialize today with new Date() and I compare the two dates- today will be after the user selected date (which is incorrect). Thus I need to initialize today at the beginning of the day without the hr/min/sec/ms.
Confusingly, Calendar months count from 0 (January) to 11 (December), so you're passing "2010-01-09" to formatter.parse() when you extract the MONTH field from the Calendar.
There's a discussion of this in a related SO question.
If you don't want to use JodaTime you could use:
Calendar calendar = Calendar.getInstance();
calendar.set( Calendar.HOUR_OF_DAY, 0 );
calendar.set( Calendar.MINUTE, 0 );
calendar.set( Calendar.SECOND, 0 );
calendar.set( Calendar.MILLISECOND, 0 );
Date today = calendar.getTime();
This is much more efficient and less error-prone than your String formatting/parsing approach.
If you can use JodaTime this is a much preferred method:
LocalDate date = new DateTime().toLocaleDate();