How to generate start and end time using Calendar? - java

I am trying to get my startTime and endTime using Calendar so that I can make my url accordingly. I need to make my startTime as yesterday midnight date 2014/09/19 00:00 and endTime for today's midnight date 2014/09/20 00:00.
So whenever I will run my program, it should generate my startTime as yesterday midnight time and endTime as the midnight of when my program is running.
I have my below code but it gets startTime as 2014/09/20 00:00 and endTime as 2014/09/20 16:00 if I am running my program now.
private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
Calendar startDate = new GregorianCalendar();
startDate.set(Calendar.MINUTE, 0);
Calendar endDate = (Calendar) startDate.clone();
startDate.set(Calendar.HOUR_OF_DAY, 0);
String startTime = df.format(startDate.getTime());
String endTime = df.format(endDate.getTime());
Is there anything wrong I am doing?

Try the following.
Calendar startDate = new GregorianCalendar();
startDate.set(Calendar.MINUTE, 0);
startDate.set(Calendar.HOUR_OF_DAY, 0);
startDate.add(Calendar.DAY_OF_MONTH, -1);
String startTime = df.format(startDate.getTime());
System.err.println(startTime);
Calendar endDate = (Calendar) startDate.clone();
endDate.add(Calendar.DAY_OF_MONTH, 1);
String endTime = df.format(endDate.getTime());
System.err.println(endTime);
It should do the job (on 2014/09/21 01:50 AM) :
2014/09/20 00:00
2014/09/21 00:00

Day Does Not Always Start at 00:00:00
Both question and the other answer assume that the first moment of the day ("midnight") is the time 00:00:00.000. Not always true because of Daylight Saving Time and possibly other anomalies.
Time Zone
Both question and the other answer ignore the issue of time zone. Determining the date depends on a time zone. Generally best to explicitly specify the intended time zone.
Joda-Time
Here is some example code using the Joda-Time 2.4 library to answer the question while addressing the two issues listed above.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( timeZone );
DateTime todayStart = now.withTimeAtStartOfDay();
DateTime tomorrowStart = now.plusDays( 1 ).withTimeAtStartOfDay();
Plus Joda-Time has three classes to represent a span of time: Interval, Period, and Duration.
Interval today = new Interval( todayStart, tomorrowStart );

Related

How do I get the String type or timestamp type by giving a year

there is a requirement to get the startTime and endTime around the whole year by giving a int year, for example, given a variable int year = 2017, I want to get the starttime String "2017-01-01 00:00:00" and endtime String "2017-12-31 23:59:59", or get the starttime timestamp 1483200000 and endtime timestamp 1514735999. 2 results are ok to us, How should I do by java8 or below? I have known:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String datetime = sdf.format(new Date(*timestamp*))
but I have no idea how I can get the timestamp by the given year, please help to check
int year = 2017;
// Using LocalDateTime (Java 8+ or Java 6+ with ThreeTen backport)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String start1 = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0).format(dtf);
String stop1 = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59).format(dtf);
System.out.println(start1 + " - " + stop1);
// Using Calendar (antiquated)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, Calendar.JANUARY, 1);
String start2 = sdf.format(cal.getTime());
cal.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
String stop2 = sdf.format(cal.getTime());
System.out.println(start2 + " - " + stop2);
Output
2017-01-01 00:00:00 - 2017-12-31 23:59:59
2017-01-01 00:00:00 - 2017-12-31 23:59:59
Use a half-open interval
As Basil Bourque said in a comment: use a half-open interval. That is, define year 2017 as the time from the first moment of 2017 inclusive to the first moment of 2018 exclusive. So any moment that is on or after the start time and strictly before the end time belongs to the year.
Philosophical argument: It saves us from deciding whether to run up to the last second, the last millisecond or the last nanosecond of the year. An even if we rook the last nano, we would still have excluded a full nano from the year, which is incorrect. Yes, I know, your application only needs a granularity of seconds, so “it doesn’t matter”. But what if the next version does require a finer granularity? And even if it won’t, you should not want to fill errors or inaccuracies into your program, not even when the user doesn’t see any symptom of them.
Practical argument: A half-open interval simplifies some things, both when calculating the timestamps and when applying them.
ZoneId zone = ZoneId.of("Asia/Singapore");
Year year = Year.of(2017);
long startTime = year.atDay(1).atStartOfDay(zone).toEpochSecond();
System.out.println(startTime);
long endTime = year.plusYears(1).atDay(1).atStartOfDay(zone).toEpochSecond();
System.out.println(endTime);
Output from this snippet is:
1483200000
1514736000
If you absolutely insist, you may of course subtract 1 from the latter number.
Notice that using atStartOfDay() also saves us from assuming that the day begins at 00:00:00 and ends a second after 23:59:59. Funny time anomalies may cause this not to be the case. Such anomalies are in the time zone database and Java takes them into account when we just query the start of day in a time zone.
You can do like this using java.sql.Timestamp
import java.util.Date;
import java.sql.Timestamp;
public class Main
{
public static void main( String[] args )
{
Date date= new Date();
long time = date.getTime();
System.out.println("Time (Milliseconds): " + time);
Timestamp ts = new Timestamp(time);
System.out.println("Current Time Stamp: " + ts);
}
}
Using Java 8 only:
int year = 2017;
// using one of the predefined format from enum java.time.format.FormatStyle
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
LocalDateTime beginDate = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0, 0);
LocalDateTime endDate = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59);
String beginDateFormatted = beginDate.format(formatter);
String endDateFormatted = endDate.format(formatter);
long beginTimestamp = this.beginDate.toInstant(ZoneOffset.UTC).toEpochMilli();
long endTimestamp = this.endDate.toInstant(ZoneOffset.UTC).toEpochMilli();
Check working example here.

date.getTime() is shorter than System.getCurrentTimeMillis()

I'm trying to create a simple Alarm Clock, but I stumbled upon a problem that I can't seem to fix. I'm trying to parse a string to a date so I can get the difference between the current time and the time to set off the alarm.
Here's my code to parse the time:
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
sdf.setTimeZone(getTimezone());
Date date = sdf.parse(args[0]);
Here's my getTimezone() method:
public static TimeZone getTimezone() {
Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
TimeZone tz = TimeZone.getTimeZone(id);
if (tz.getRawOffset() == milliDiff) {
// Found a match.
name = id;
break;
}
}
return TimeZone.getTimeZone(name);
}
And here's my code for figuring out the difference:
long diff = date.getTime() - System.currentTimeMillis();
So my problem is that the date.getTime() returns 79680000, while System.currentTimeMillis() returns 1473538047978 (This is of course different every time, but for some odd reason, date.getTime() is not).
Which means that I get a negative number when trying to figure out the difference, and therefore I cannot use it.
EDIT: After a little bit of debugging, I realised that it has to do with the year, month and day not being set, however I do not know how to get those.
You did notice that date.getTime() returns 79680000 which is 22 hours and 20 minutes after 1 January 1970. The problem is (as you noticed) that you did not parse year, month and day.
You can do it by:
SimpleDateFormat sdf = new SimpleDateFormat("DD/MM/YYYY hh:mm:ss");
Example input 20/04/2016 20:20:0 returns time as Mon Jan 04 20:20:00 CET 2016 (don't look at the timezone). It is 1451935200000 miliseconds after 1 January 1970.
Note: change string to match your format requirements (the syntax is self-explanatory).
The accepted answer by Ronin is correct. You are trying to put a time-of-day value into a date-time type.
java.time
Also, you are using troublesome old legacy date-time classes. Now supplanted by the java.time classes.
For a time-of-day value without a date and without a time zone, use LocalTime.
LocalTime alarmTime = LocalTime.parse( "12:34" );
Getting current time-of-day requires a time zone.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalTime now = LocalTime.now( z );
But since we are setting an alarm, we care about the date too.
ZonedDateTime now = ZonedDateTime.now( z );
ZonedDateTime alarm = null;
if ( now.toLocalTime().isBefore( alarmTime ) ) {
alarm = ZonedDateTime.of( now.toLocalDate() , alarmTime , z );
} else {. // Else too late for today, so set alarm for tomorrow.
alarm = ZonedDateTime.of( now.toLocalDate().plusDays( 1 ) , alarmTime , z );
}
To calculate the elapsed time until the alarm, use the Duration class.
Duration untilAlarm = Duration.between( now , alarm );
You can interrogate the duration for a total number of milliseconds. But know that java.time classes are capable of handling nanoseconds.
long millis = untilAlarm.toMillis();
Updated.
You are using only time without a date with you date object in code (parses only time). If you add there date to you time, your date should be comparable to your System.getCurrentTimeMillis() call. And if you subtracting current millis from date in the past, you will have negative numbers. I prefer this convertion (date2 is after date1):
long diffInMillies = date2.getTime() - date1.getTime();
return TimeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);

How to get time 2 hours earlier using Calendar API?

I need to get my start date and time as todays date and time should be 00:00 but end time should be current hour - 2. With me below code, I am not able to understand how to get end time as current hour - 2.
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
Calendar startDate = new GregorianCalendar();
startDate.set(Calendar.MINUTE, 0);
Calendar endDate = (Calendar) startDate.clone();
startDate.set(Calendar.HOUR_OF_DAY, 0);
String startTime = df.format(startDate.getTime());
String endTime = df.format(endDate.getTime());
System.out.println(startTime);
System.out.println(endTime);
If I run the above code just now, this is what gets printed out :
2015/08/17 00:00
2015/08/17 12:00
But I want to have end time as 10:00 which is 2 hours earlier than noon time so it should print this:
2015/08/17 00:00
2015/08/17 10:00
How can I do this?
UPDATE:-
This is what I have tried:
Calendar startDate = new GregorianCalendar();
startDate.set(Calendar.MINUTE, 0);
Calendar endDate = new GregorianCalendar();
endDate.add(Calendar.HOUR, -2);
String startTime = df.format(startDate.getTime());
String endTime = df.format(endDate.getTime());
System.out.println(startTime);
System.out.println(endTime);
And this is what it is printing out:
2015/08/17 12:00
2015/08/17 10:53
You can use the Calendar's add(int field, int amount) method to add a negative number of hours. Like so:
Calendar date = new GregorianCalendar();
date.add(Calendar.HOUR, -2);
Link to the documentation

How to add current time to a previous date in java?

I was trying to add current time into previous date. But it was adding in current date with time not with previous date.
see my bellow code:
Date startUserDate = ;//this is my previous date object;
startUserDate.setTime(new Date().getTime());// here i'm trying to add current time in previous date.
System.out.println("current time with previous Date :"+startUserDate);
In previous date there is no time and i want to add current time in previous date.I can do this, please help me out.
Use calendar object
Get instance of calendar object and set your past time to it
Date startUserDate = ;
Calendar calendar = Calendar.getInstance();
calendar.settime(startUserDate);
Create new calendar instance
Calendar cal = Calendar.getInstance();
cal.settime(new Date());
format the date to get string representation of time of current date
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentdate = sdf.format(cal.getTime());
split that string to get hour minute and second object
String hh = expiry.split(":")[0];
String mm = expiry.split(":")[1];
String ss = expiry.split(":")[2];
add it to the previous calendar object
calendar .add(Calendar.HOUR_OF_DAY, hh);
calendar .add(Calendar.MINUTE, mm);
calendar .add(Calendar.SECOND, ss);
this date will have current time added to your date
Date newDate = calendar.getTime;
Use Calendar:
first set the date/time of the first calendar object to the old date
object use as second Calendar object to set the current time on the
first calendar object then convert it back to date
as follow:
//E.g. for startUserDate
Date startUserDate = new Date(System.currentTimeMillis() - (24L * 60L * 60L * 1000L) - (60L * 60L * 1000L));//minus 1 day and 1 hour
Calendar calDateThen = Calendar.getInstance();
Calendar calTimeNow = Calendar.getInstance();
calDateThen.setTime(startUserDate);
calDateThen.set(Calendar.HOUR_OF_DAY, calTimeNow.get(Calendar.HOUR_OF_DAY));
calDateThen.set(Calendar.MINUTE, calTimeNow.get(Calendar.MINUTE));
calDateThen.set(Calendar.SECOND, calTimeNow.get(Calendar.SECOND));
startUserDate = calDateThen.getTime();
System.out.println(startUserDate);
The second Calendar object calTimeNow can be replaced with Calendar.getInstance() where it is used.
You can do it using DateFormat and String, here's the solution that you need:
Code:
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
String timeString = df.format(new Date()).substring(10); // 10 is the beginIndex of time here
DateFormat df2 = new SimpleDateFormat("MM/dd/yyyy");
String startUserDateString = df2.format(startUserDate);
startUserDateString = startUserDateString+" "+timeString;
// you will get this format "MM/dd/yyyy HH:mm:ss"
//then parse the new date here
startUserDate = df.parse(startUserDateString);
Explanation:
Just convert the current date to a string and then extract the time from it using .substring() method, then convert your userDate to a string concatenate the taken time String to it and finally parse this date to get what you need.
Example:
You can see it working in this ideone DEMO.
Which takes 02/20/2002 in input and returns 02/20/2002 04:36:14 as result.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date and time work.
ZoneId zone = ZoneId.systemDefault();
LocalDate somePreviousDate = LocalDate.of(2018, Month.NOVEMBER, 22);
LocalTime timeOfDayNow = LocalTime.now(zone);
LocalDateTime dateTime = somePreviousDate.atTime(timeOfDayNow);
System.out.println(dateTime);
When I ran the code just now — 16:25 in my time zone — I got this output:
2018-11-22T16:25:53.253892
If you’ve got an old-fashioned Date object, start by converting to a modern Instant and perform further conversion from there:
Date somePreviousDate = new Date(1_555_555_555_555L);
LocalDate date = somePreviousDate.toInstant().atZone(zone).toLocalDate();
LocalTime timeOfDayNow = LocalTime.now(zone);
LocalDateTime dateTime = date.atTime(timeOfDayNow);
2019-04-18T16:25:53.277947
If conversely you need the result as an old-fashioned Date, also convert over Instant:
Instant i = dateTime.atZone(zone).toInstant();
Date oldfasionedDate = Date.from(i);
System.out.println(oldfasionedDate);
Thu Nov 22 16:25:53 CET 2018
Link
Oracle tutorial: Date Time explaining how to use java.time.
The getTime method returns the number of milliseconds since 1970/01/01 so to get the time portion of the date you can either use a Calendar object or simply use modula arithmetic (using the above milliseconds value and the MAX millseconds in a day) to extract the time portion of the Date.
Then when you have the time you need to add it to the second date,
but seriously, use http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
and use things like get (HOUR) and get (MINUTE) etc. which then you can use with set (HOUR, val)
You need to use Calendar class to perform addition to Dateobject. Date's setTime() will set that time in Date object but not add i.e it will overwrite previous date. new Date().getTime() will not return only time portion but time since Epoch. Also, how did you manipulated , startUserDate to not have any time (I mean , was it via Calendar or Formatter) ?
See Answer , Time Portion of Date to calculate only time portion,
long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
Date now = Calendar.getInstance().getTime();
long timePortion = now.getTime() % MILLIS_PER_DAY;
then you can use something like, cal.add(Calendar.MILLISECOND, (int)timePortion); where cal is Calendar object corresponding to your startUserDate in your code.
Calendar calendar = Calendar.getInstance();
calendar.setTime(startUserDate );
//new date for current time
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentdate = sdf.format(new Date());
String hhStr = currentdate.split(":")[0];
String mmStr = currentdate.split(":")[1];
String ssStr = currentdate.split(":")[2];
Integer hh = 0;
Integer mm = 0;
Integer ss = 0;
try {
hh = Integer.parseInt(hhStr);
mm = Integer.parseInt(mmStr);
ss = Integer.parseInt(ssStr);
}catch(Exception e) {e.printStackTrace();}
calendar.set(Calendar.HOUR_OF_DAY, hh);
calendar.set(Calendar.MINUTE, mm);
calendar.set(Calendar.SECOND, ss);
startUserDate = calendar.getTime();

Subtracting two dates in Java

I want to subtract two dates (one constant and one current) in Java but I've got strange problems with it. Here is the code :
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
Date currentTime = new Date();
long diff = FirstLessonInterval.getTime()-currentTime.getTime();
String s = String.valueOf(diff);
LessonOrBreak=(diff);
I've got minus minutes. When I want to see FirstLessonInterval with FirstLessonInterval.toString() it shows the year 1970. What can I do?
You forgot to give a date, you just defined a time:
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
and this is in unix time day 0 which is the 1.1.1970
try something like
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:MM");
Date FirstLessonInterval=df.parse("2014/05/10 08:45");
1970 is where all time began according to computers. Are we missing some code in your question? You can faff around with the current time in milliseconds but i'd take a look at JodaTime and use that.
The reason you are getting 1970.... is because I suspect your diff is quite a small number. Then if you look at that as a date then it will be a small number + 1 Jan 1970 which will still be in 1970. But as i said I suspect we are missing some code in your question.
In JodaTime you can do somethign like the below but im not sure what it is you are exactly after
Interval i= new Interval(new DateTime(FirstLessonInterval), new DateTime());
System.out.println("Interval is: " + i.toDurationMillis());
Your format pattern is incorrect, use lower case mm to represent minutes
When you do not specify much details to the outdated Java date api, it considers the time since UNIX epoch (1st Jan 1970)
Since you are assuming the date to be the same as the constant time parameters you provide and independent of the timezones, you can bring your current date comparable to the time since UNIX epoch:
Staying close to your original code;
DateFormat df = new SimpleDateFormat("HH:mm");
Date firstLessonInterval = df.parse("08:45");
Date currentTime = new Date();
// Format the current date comparable to UNIX epoch (only hold time params)
String dateStr = df.format(currentTime.getTime());
// Parse the modified date string to a date object
Date comDate = df.parse(dateStr);
// Take the difference in millis
long diff = firstLessonInterval.getTime() - comDate.getTime();
String s = String.valueOf(diff);
// Print the number of minutes passed since
System.out.println("Minutes {elapsed since/time to} 08:45 - " + Math.abs(diff) / 1000 / 60);
Missing Date Portion
As the other correct answers said, you are using the java.util.Date class which is a date-time class holding both a date portion and a time portion.
LocalTime
If you truly care about only time of day, with no date and no time zone, then use the LocalTime class found in both the Joda-Time library and the new java.tome package in Java 8. By the way the old java.util.Date and .Calendar classes are notoriously troublesome and should be avoided.
Joda-Time
Here is some code with date-time and time zone.
Using the Joda-Time 2.3 library…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Warsaw" );
DateTime dateTime = new DateTime( 2014, 1, 2, 8, 45, 0, timeZone );
DateTime now = new DateTime( 2014, 1, 2, 8, 30, 0, timeZone ); // Or DateTime.now( timeZone )
Duration duration = new Duration( dateTime, now ); // or use Period or Interval.
Joda-Time offers intelligent classes and methods of working with a span of time (a Period, Interval, or Duration). For example look at the Minutes class. But if all you need is millseconds, here you go.
long millis = duration.getMillis();
The problem is that you are not providing enough info to SimpleDateFormat. It sets the hour and minutes correctly but nothing else.
DateFormat df = new SimpleDateFormat("HH:mm");
System.out.println(df.parse("08:45")); // Thu Jan 01 08:45:00 GMT 1970
System.out.println(new Date()); // Sun May 11 07:52:50 GMT 2014
If you want your date to be with respect to the current date try this:
Date curr = new Date();
Date date = new Date(curr.getYear(),
curr.getMonth(),
curr.getDate(),
8, 45, 0);
System.out.println(date); // Sun May 11 08:45:00 GMT 2014
System.out.println(curr); // Sun May 11 07:52:50 GMT 2014
long diff = date.getTime() - curr.getTime();
System.out.println("Minutes: " + diff/6000); // Minutes: 53
I dont know if this way is efficient or not but it's an idea anyway:
Date curr = new Date();
Date date = new Date(114, /*114 is 2014 , don't know why*/
6,
16,
8, 45, 0);
System.out.println(curr);
System.out.println(date);
Date x = new Date(curr.getYear() - date.getYear() ,
curr.getMonth() - date.getMonth(),
curr.getDate() - date.getDate(),
curr.getHours() - date.getHours(),
curr.getMinutes() - date.getMinutes(),
curr.getSeconds() - date.getSeconds() );
String startDateString = "2017-03-08";
String finishDateString = "2017-03-10";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
LocalDate startDate = LocalDate.parse(startDateString, formatter);
LocalDate finishDate = LocalDate.parse(finishDateString, formatter);
Integer day = finishDate.compareTo(startDate);
Integer day will be 3. It means that the difference between two dates equals 3 days

Categories