Related
I had previously created a question about this but I am still having problems.
I want to create a cooldown for player challenges. Currently there are two types of cooldowns, DAILY and WEEKLY.
The Daily cooldown lasts from the time the challenge is completed until 23:59 of the day, that is if you complete it at 14:00 you would have to wait 9 hours for the challenge to be enabled again.
The weekly cooldown is the same but the challenge is enabled until Thursday night, then the remaining time would be until Thursday night
So I want to get the hours, minutes and seconds until the cooldown ends but I can't get it right, I get giant numbers or it just doesn't work. I have never worked with dates and times, this would be my first time.
When a challenge is completed I store the date and time it was completed, something like this: 10-12-2021 and 20:33:58. Then I get them in the code to calculate the remaining time but when I get the String I get "-1" something like: 7d 10623m 637385s or 1d 2753m 1935s
My code for Daily:
public String getDailyCountdown(UUID uuid, Quest quest) {
QuestProperties questProperties = plugin.getQuestsCache().get(uuid, quest);
String countdownTimePlaceholder = "";
String[] completionDate = questProperties.getCompletionDate().split("-"), completionTime = questProperties.getCompletionTime().split(":");
int completionDay = Integer.parseInt(completionDate[0]), completionMonth = Integer.parseInt(completionDate[1]), completionYear = Integer.parseInt(completionDate[2]);
int completionHour = Integer.parseInt(completionTime[0]), completionMinutes = Integer.parseInt(completionTime[1]), completionSeconds = Integer.parseInt(completionTime[2]);
LocalDateTime fromDateTime = LocalDateTime.of(completionYear, completionMonth, completionDay, completionHour, completionMinutes, completionSeconds);
LocalDateTime toDateTime = LocalDateTime.of(2021, 11, 25, 23, 59, 0);
long current = System.currentTimeMillis();
long durationMillis = Duration.between(fromDateTime, toDateTime).toMillis();
Duration duration = Duration.between(fromDateTime, toDateTime);
long s = duration.getSeconds();
long s2 = s * 1000L;
long waitingTime = current - durationMillis;
long div = waitingTime / 1000L;
long waitingSeconds = s - div, waitingMinutes = waitingSeconds / 60L, waitingTimeHours = waitingMinutes / 60L;
if (durationMillis + s2 > current && durationMillis != 0L) {
if (waitingMinutes > 59L) waitingMinutes -= 60L * waitingTimeHours;
if (waitingMinutes > 0L) countdownTimePlaceholder = waitingMinutes + "m" + countdownTimePlaceholder;
if (waitingTimeHours > 0L) countdownTimePlaceholder = waitingTimeHours + "h" + countdownTimePlaceholder;
return countdownTimePlaceholder;
}
return "-1";
}
My code for Weekly:
QuestProperties questProperties = plugin.getQuestsCache().get(uuid, quest);
String countdownTimePlaceholder;
String[] completionDate = questProperties.getCompletionDate().split("-"), completionTime = questProperties.getCompletionTime().split(":");
int completionDay = Integer.parseInt(completionDate[0]), completionMonth = Integer.parseInt(completionDate[1]), completionYear = Integer.parseInt(completionDate[2]);
int completionHour = Integer.parseInt(completionTime[0]), completionMinutes = Integer.parseInt(completionTime[1]), completionSeconds = Integer.parseInt(completionTime[2]);
LocalDateTime fromDateTime = LocalDateTime.of(completionYear, completionMonth, completionDay, completionHour, completionMinutes, completionSeconds);
LocalDateTime toDateTime = LocalDateTime.now().plusDays(7);
LocalDateTime localDateTime = LocalDateTime.from(fromDateTime);
long days = localDateTime.until(toDateTime, ChronoUnit.DAYS);
long minutes = localDateTime.until(toDateTime, ChronoUnit.MINUTES);
long seconds = localDateTime.until(toDateTime, ChronoUnit.SECONDS);
countdownTimePlaceholder = days + "d" + minutes + "m" + seconds + "s";
return countdownTimePlaceholder;
How could I do it better or make it get the remaining time correctly?
Regards.
Date-time handling is tricky
You said:
I have never worked with dates and times, this would be my first time.
Date-time handling is surprisingly difficult and confusing. Be patient, study well, and run experiments.
Search Stack Overflow, as your issues have already been addressed many times. I’ll try to be brief here. Search to learn more and see more code examples.
Store date-time objects
As commented by Boris The Spider, use java.time to store your date-time values rather than repeatedly parsing their textual representation.
Or is QuestProperties outside your control?
If outside your control, at least simplify your parsing code. Change this:
int completionDay = Integer.parseInt(completionDate[0]), completionMonth = Integer.parseInt(completionDate[1]), completionYear = Integer.parseInt(completionDate[2]);
int completionHour = Integer.parseInt(completionTime[0]), completionMinutes = Integer.parseInt(completionTime[1]), completionSeconds = Integer.parseInt(completionTime[2]);
… to this:
LocalDate ld = LocalDate.of( Integer.parseInt(completionDate[2]) , Integer.parseInt(completionDate[1]) , Integer.parseInt(completionDate[0]) ) ; // year, month, day.
LocalTime lt = LocalTime.of( Integer.parseInt(completionTime[0]) , Integer.parseInt(completionTime[1]) , Integer.parseInt(completionTime[2]) ) ; // hour, minute, second.
Half-Open
Spans of time are usually best handled using Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. So a day starts at the first moment of the day and runs up to, but does not include, the first moment of the following day.
Your code LocalDateTime.of(2021, 11, 25, 23, 59, 0) fails to account for the last full minute of the day, the minute between 23:59:00 and 00:00:00.
Change to:
LocalDateTime toDateTime = fromDateTime.toLocalDate().plusDays( 1 ).atStartOfDay() ;
Time zone
Your biggest problem is that you are ignoring the crucial issue of time zone. Getting the date, and determining the first moment of the day time, requires a time zone.
A day ends much earlier in the east than in the west. For example, at some moments, the date can be “tomorrow” in Tokyo Japan 🇯🇵 while simultaneously still “yesterday” in Edmonton Canada 🇨🇦.
So if you want to run your cooldowns to the end of the day as seen by the user, then you must account for the user’s time zone. You can query for their current default time zone. But ultimately best to confirm with the user.
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
Capture the current moment as seen in that zone.
ZonedDateTime zdtNow = ZonedDateTime.now( z );
The LocalDateTime is the wrong class for your needs. That class represents a date and a time-of-day but lacks the context of a time zone or offset-from-UTC. We used ZonedDateTime to represent the current moment with a date, a time-of-day, and a time zone.
LocalDateTime = 🗓 + 🕛
ZonedDateTime = 🗓 + 🕛 + 🗺
Get the first moment of the next day. Notice how we ask java.time to determine when the day starts on that date in that zone. Do not assume a day starts at 00:00:00. Days may start at other times.
ZonedDateTime zdtStartOfTomorrow = zdtNow.toLocalDate().plusDays( 1 ).atStartOfDay( z ) ;
Time to elapse
If needed, calculate time to elapse.
Duration d = Duration.between( zdtNow , zdtStartOfTomorrow ) ;
Compare later moments to see if the deadline has passed.
if( ZonedDateTime.now( z ).isAfter( zdtStartOfTomorrow ) ) { … cooldown ended … }
Retrieving moment in UTC
In your case we do not want the current moment. We want to retrieve the user’s moment of last activity from your Quest system.
We parsed need date and the time above, in earlier part of this Answer. But your code did not account for retrieving the time zone. So I will assume the retrieved date and time are as seen « in UTC », with an offset of zero hours-minutes-seconds.
OffsetDateTime odt = OffsetDateTime.of( ld , lt , ZoneOffset.UTC ) ;
Adjust that to the user’s desired time zone.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Capturing the current moment
You asked:
When a challenge is completed I store the date and time it was completed, something like this: 10-12-2021 and 20:33:58.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
To generate text representing that moment for data exchange, call toString. For text to present to user, let DateTimeFormatter class automatically localize. Both cases have been covered many times already on Stack Overflow.
This question already has answers here:
Getting specific date with timezone in Java
(1 answer)
how to get dateTime based on hour and minute
(4 answers)
Closed 1 year ago.
I am running a script in Jenkins. One piece of the script need to run at 07:00:00 Eastern Time.
The job is already scheduled on specific days and time. The job starts at 6am, but need to wait until 7am to run the next step
Using java, I can get current time/date using:
Date currentDate = new Date()
I think I need to compare currentDate with today's date at 7am so I can know how many seconds there is until 7am and put my build to sleep for that time.
My question is, how can I generate today's date at 7am?
Avoid using the terrible Date class. The legacy date-time classes were years ago supplanted by the modern java.time classes defined in JSR 310.
Capture the current moment as seen in your particular time zone.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Define your target.
LocalTime targetTime = LocalTime.of( 7 , 0 ) ;
Adjust to that time.
ZonedDateTime zdtTarget = zdt.with( targetTime ) ;
If that moment has passed, move to next day.
if( ! zdt.isBefore( zdtTarget ) ) {
zdtTarget = zdt.toLocalDate().plusDays( 1 ).atStartOfDay( z ).with( targetTime ) ;
}
Determine time to elapse.
Duration d = Duration.between( zdt.toInstant() , zdtTarget.toInstant() ) ;
Interrogate the duration object for whatever you need. For example, milliseconds:
long millis = d.toMillis() ;
Thread.sleep( millis ) ;
If you must use a java.until.Date for code not yet updated to java.time, you can convert.
java.until.Date date = Date.from( zdtTarget.toInstant() ) ;
Great question. It's easier to first create a Calendar object to set up the time, date and other custom inputs, then convert that to a Date object using the <CALENDAR_OBJECT>.getTime() member function.
EX: to get a Date object of 7 am today(10/25/2021) do the following:
Calendar cal = Calendar.getInstance(); // Calendar constructor
cal.set(Calendar.YEAR, 2021);
cal.set(Calendar.MONTH, 10);
cal.set(Calendar.DAY_OF_MONTH, 25);
cal.set(Calendar.HOUR_OF_DAY,7);
cal.set(Calendar.MINUTE,00);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Date d = cal.getTime(); // convert to Date obj
For more info on the Calendar obj look at some documentation by Oracle (https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html)
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);
I am developing and android app, where I need to calculate the difference between two times.I need to calculate the time difference for 24 hrs, and also the difference between times on two days(Eg. 5pm today to 9 am tomorrow).
I have tried the below code, to calculate the difference which works only for 24 hrs,
String dateStart = "08:00:00";
String dateStop = "13:00:00";
//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Date d1 = null;
Date d2 = null;
try
{
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
//in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffHours = diff / (60 * 60 * 1000) % 24;
Log.e("test",diffHours + " hours, ");
}
catch (Exception e)
{
// TODO: handle exception
}
Sir, you can make it easily in using java feature. long difference = date2.getTime() - date1.getTime(); Take a look in this link this will help you.
Correct way to find proper time difference:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
Date startDate = simpleDateFormat.parse("22:00:59");
Date endDate = simpleDateFormat.parse("23:00:10");
long difference = endDate.getTime() - startDate.getTime();
if(difference<0)
{
Date dateMax = simpleDateFormat.parse("24:00:00");
Date dateMin = simpleDateFormat.parse("00:00:00");
difference=(dateMax.getTime() -startDate.getTime() )+(endDate.getTime()-dateMin.getTime());
}
int days = (int) (difference / (1000*60*60*24));
int hours = (int) ((difference - (1000*60*60*24*days)) / (1000*60*60));
int min = (int) (difference - (1000*60*60*24*days) - (1000*60*60*hours)) / (1000*60);
int sec = (int) (difference - (1000*60*60*24*days) - (1000*60*60*hours) - (1000*60*min)) / (1000);
Log.i("log_tag","Hours: "+hours+", Mins: "+min+", Secs: "+sec);
Result will be: Hours: 0, Mins: 59, Secs: 11
tl;dr
ChronoUnit.HOURS.between(
LocalTime.parse( "08:00:00" ) ,
LocalTime.parse( "13:00:00" )
)
5
…or…
ChronoUnit.HOURS.between(
ZonedDateTime.of(
LocalDate.of( 2017 , Month.JANUARY , 23 ) ,
LocalTime.parse( "08:00:00" ) ,
ZoneId.of( "America/Montreal" )
) ,
ZonedDateTime.of(
LocalDate.of( 2017 , Month.JANUARY , 25 ) ,
LocalTime.parse( "13:00:00" ) ,
ZoneId.of( "America/Montreal" )
)
)
53
java.time
Modern approach uses the java.time classes.
LocalTime
The LocalTime class represents a time-of-day without a date and without a time zone.
LocalTime start = LocalTime.parse( "08:00:00" ) ;
LocalTime stop = LocalTime.parse( "13:00:00" ) ;
Duration
Get a Duration object to represent the span-of-time.
Duration d = Duration.between( start , stop ) ;
ChronoUnit
For number of hours, use ChronoUnit.
long hours = ChronoUnit.HOURS.between( start , stop ) ;
Android
For Android, see the ThreeTen-Backport and ThreeTenABP projects. See last bullets below.
ZonedDateTime
If you want to cross days, going past midnight, you must assign dates and time zones.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime start = ZonedDateTime.of(
LocalDate.of( 2017 , Month.JANUARY , 23 ) ,
LocalTime.parse( "08:00:00" ) ,
z
) ;
ZonedDateTime stop = ZonedDateTime.of(
LocalDate.of( 2017 , Month.JANUARY , 25 ) ,
LocalTime.parse( "13:00:00" ) ,
z
) ;
long hours = ChronoUnit.HOURS.between( start , stop ) ;
See this code run live at IdeOne.com.
53
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
You can try something like this also if you are sure the 9 am is next day you can add one day and calculate the difference:
String string1 = "05:00:00 PM";
Date time1 = new SimpleDateFormat("HH:mm:ss aa").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
String string2 = "09:00:00 AM";
Date time2 = new SimpleDateFormat("HH:mm:ss aa").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
Date x = calendar1.getTime();
Date xy = calendar2.getTime();
long diff = x.getTime() - xy.getTime();
diffMinutes = diff / (60 * 1000);
float diffHours = diffMinutes / 60;
System.out.println("diff hours" + diffHours);
Try simple piece of code using For 24 hour time
StartTime = "10:00";
EndTime = "13:00";
here starthour=10 and end hour=13
if(TextUtils.isEmpty(txtDate.getText().toString())||TextUtils.isEmpty(txtDate1.getText().toString())||TextUtils.isEmpty(txtTime.getText().toString())||TextUtils.isEmpty(txtTime1.getText().toString()))
{
Toast.makeText(getApplicationContext(), "Date/Time fields cannot be blank", Toast.LENGTH_SHORT).show();
}
else {
if (starthour > endhour) {
Toast.makeText(getApplicationContext(), "Start Time Should Be Less Than End Time", Toast.LENGTH_SHORT).show();
} else if (starthour == endhour) {
if (startmin > endmin) {
Toast.makeText(getApplicationContext(), "Start Time Should Be Less Than End Time", Toast.LENGTH_SHORT).show();
}
else{
tvalid = "True";
}
} else {
// Toast.makeText(getApplicationContext(),"Sucess"+(endhour-starthour)+(endmin-startmin),Toast.LENGTH_SHORT).show();
tvalid = "True";
}
}
same for date also
I worked it out this way:
Date time1 = new SimpleDateFormat("HH:mm:ss aa").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
Date time2 = new SimpleDateFormat("HH:mm:ss aa").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
if(calendar2.get(Calendar.AM_PM) == 1 && calendar1.get(Calendar.AM_PM) == 0) {
calendar2.add(Calendar.DATE, 1);
}
long diff = calendar1.getTimeInMillis() - calendar2.getTimeInMillis()
This will help to find the difference in time round the clock.
I am seriously looking for this code...I am new programmer.
Actually I want to make all dates with flag, which all are sunday in a particular year.
Please, I am eagerly waiting for your response....
Create a new calendar. Set the time to 1/1/yyyy and some time. Check if the current date is a Sunday and roll forward one day until it is. That's the first Sunday of the year. Roll forward 7 days until the year no longer matches, marking as you go.
Study the the docs of java.util.Calendar carefully.
If i was doing it I would use Joda Time to find the first Sunday in the year using LocalDate. Create 1st of Jan and then add 1 day until it is a Sunday, then add 7 days until your run out of year.
LocalDate date = new LocalDate(YEAR, 1, 1);
while ( date.dayOfWeek() != 7 )
{
date = date.addDays(1);
}
while ( date.year() == YEAR )
{
date = date.addDays(7);
}
Or something like that.
Something like this should work.
int year = 2009;
Calendar cal = new GregorianCalendar(year, Calendar.JANUARY, 1);
for (int i = 0, inc = 1; i < 366 && cal.get(Calendar.YEAR) == year; i+=inc) {
if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
// this is a sunday
cal.add(Calendar.DAY_OF_MONTH, 7);
inc = 7;
} else {
cal.add(Calendar.DAY_OF_MONTH, 1);
}
}
This is an example code using java.util.Calendar and java.util.GregorianCalendar that prints out each Sunday of the year 2009.
A lot of optimizing can be done in formatting the date, but i'll leave that as an exercise for you.
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Test
{
public static void main(String[] args)
{
int year =2009;
int dayOfWeek = Calendar.SUNDAY;
String dayOfWeekString = "Sunday";
// instantiate Calender and set to first Sunday of 2009
Calendar cal = new GregorianCalendar();
cal.set(2009, 0, 1, 0, 0); cal.getTime();
cal.set(Calendar.DAY_OF_WEEK, dayOfWeek); cal.getTime();
int i = 1;
while (cal.get(Calendar.YEAR) == 2009)
{
System.out.println(dayOfWeekString + " " + i + ": " + cal);
cal.add(Calendar.DAY_OF_MONTH, 7);
i++;
}
}
}
As you can see, TiGz's way of using Joda Time is a lot simpler.
List arrList = new ArrayList();
SimpleDateFormat format1 = new SimpleDateFormat("dd-M-yyyy");
Date date = null;
Calendar cal = Calendar.getInstance();
for (int i = 0; i <= 51; i++)
{
try
{
cal.add(Calendar.WEEK_OF_YEAR, +1);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
String formatted = format1.format(cal.getTime());
date = format1.parse(formatted);
arrList.add(date);
} catch (Exception e) {
e.printStackTrace();
}
}
java.time
Java 8 and later comes with the new java.time package. Inspired by Joda-Time, defined by JSR 310, extended by the ThreeTen-Extra project. These new classes supplant the notoriously troublesome java.util.Date/.Calendar & java.text.SimpleDateFormat and such.
Note that we specify a time zone, crucial for determining a date. For example, a new day dawns earlier in Paris than in Montréal.
ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Time zone is crucial in determining the date. A new day dawns earlier in Paris than In Montréal, for example.
You would write this code to use only LocalDate without any time-of-day. But in business, the full date-time is often more useful. So my example here uses ZonedDateTime.
To be neat, I want the time-of-day set to first moment of the day. You might assume that means 00:00:00.0 but not always because of anomalies such as Daylight Saving Time. To soft-code this first-moment, we want to call the atStartOfDay method found on LocalDate. So we start with LocalDate, then use that method to get a ZonedDateTime object.
Again, note that we specify a time zone when getting today’s date. A very common mistake is to omit time zone. When omitted, the JVM’s current default time zone will be implicitly applied. That means your results can vary by machine or by admin’s settings. Even worse, any code in any thread of any app within this JVM can make a call to change that default time zone at any moment during runtime while your app executes! So always specify rather than rely implicitly on current default.
LocalDate today = LocalDate.now( zoneId ); // We want a ZonedDateTime, but starting with a LocalDate in order to get first moment of the day (see next line).
ZonedDateTime todayStart = today.atStartOfDay( zoneId ); // Set time-of-day to first moment of this date, just to be neat. Usually that time is '00:00:00.0' but not always.
The java.time framework includes some handy TemporalAdjustors to get first day of year, and from there, the first Sunday of that month.
ZonedDateTime firstOfThisYear = todayStart.with( TemporalAdjusters.firstDayOfYear( ) );
ZonedDateTime zdtFirstOfNextYear = firstOfThisYear.with( TemporalAdjusters.firstDayOfNextYear( ) );
ZonedDateTime firstSundayOfThisYear = firstOfThisYear.with( TemporalAdjusters.dayOfWeekInMonth( 1, DayOfWeek.SUNDAY ) );
Now we are set to loop through all the weeks of the year. We increment a week at a time until we find ourselves in the next year. We collect each Sunday in a List.
ZonedDateTime zdt = firstSundayOfThisYear; // Var changing throughout loop.
List< ZonedDateTime > sundays = new ArrayList<>( 53 ); // Set initial capacity to maximum number of values.
while ( zdt.isBefore( zdtFirstOfNextYear ) ) {
// Handle this iteration.
sundays.add( zdt );
System.out.println( "Sunday # " + sundays.size( ) + " : " + zdt );
// Prepare next iteration.
zdt = zdt.plusWeeks( 1 );
}
When run.
Sunday # 1 : 2015-01-04T00:00-05:00[America/Montreal]
Sunday # 2 : 2015-01-11T00:00-05:00[America/Montreal]
…
Sunday # 51 : 2015-12-20T00:00-05:00[America/Montreal]
Sunday # 52 : 2015-12-27T00:00-05:00[America/Montreal]
A year has approximately 365 days, so the Big-O's n is pretty manageable. I'd say just iterate from the beginning of the year through to the last day of the year, and check if each day is a Sunday or not.
You need at least Calendar.get(), Calendar.DAY_OF_WEEK and Calendar.SUNDAY
I recently developed [Lamma Date] which is designed to serve this type of use cases.
Following code will print out all Sundays in 2014:
List<Date> sundays2014 = Dates.from(2014, 1, 1).to(2014, 12, 31).byWeek().on(DayOfWeek.SUNDAY).build();
for(Date date: sundays2014) {
System.out.println(date);
}
**this will give u all Sundays of the year **
invented By me and friend Hemant
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class Test {
public static void main(String[] args) {
SimpleDateFormat format =new SimpleDateFormat("dd-MMM-yyyy");
String DATE_FORMAT = "yyyy MM dd";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Calendar c1 = Calendar.getInstance(); // today
String y=sdf.format(c1.getTime());
String years=y.substring(0,4);
int year=Integer.parseInt(years);
//Connection con=null;
Calendar cal = new GregorianCalendar(year, Calendar.JANUARY, 1);
for (int i = 0, inc = 1; i <366 && cal.get(Calendar.YEAR) == year; i+=inc) {
if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
// this is a sunday
String frm="";
frm=format.format(cal.getTime());
//System.out.println("From :"+frm);
System.out.println("the value of the sunday is "+format.format(cal.getTime()));
cal.add(Calendar.DAY_OF_MONTH, 7);
} else {
cal.add(Calendar.DAY_OF_MONTH, 1);
}
}
}
}