Convert month and day number to day of year using CALENDAR - java

I have two numbers.
First would be the month number.
Second would be the day number.
I also know the year.
How can I take those two number, month and day and make it into a single number DAY_OF_YEAR?
I'm using Java 1.7 and the Calendar functions.

java.time through ThreeTen Backport
int year = 2019;
int monthNumber = 9;
int dayNumber = 28;
LocalDate date = LocalDate.of(year, monthNumber, dayNumber);
int dayOfYear = date.getDayOfYear();
System.out.println("Day of year is " + dayOfYear);
Output from this snippet is:
Day of year is 271
Tested on Java 1.7.0_79 using ThreeTen Backport 1.3.6 and importing org.threeten.bp.LocalDate.
Consider avoiding the Calendar class
Four lines of the currently accepted answer creating and setting the Calendar object are substituted by just one line here. It’s typical for code using Calendar to be so wordy, which we shouldn’t want. Also despite the name a Calendar object is more than a calendar date, it also carries with it a time of day, a time zone and more, so I do not consider it a good fit for the job at hand. The code using Calendar will give a different result if the default locale is Thai, which will surprise most. The Calendar class is poorly designed and long outdated.
Instead I am using LocalDate of java.time, the modern Java date and time API.
Question: Can I use java.time on Java 7?
I'm using Java 1.7 …
java.time works nicely on Java 7. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Just using calendar and assuming by number of month you mean the zero-indexed one where 0 means January, here is an example for May 13th 2019:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
c.set(Calendar.YEAR, 2019);
c.set(Calendar.MONTH, 4);
c.set(Calendar.DAY_OF_MONTH, 13);
System.out.println(c.get(Calendar.DAY_OF_YEAR));
Edit: As Ole V.V.'s answer pointed out you get a Calendar object with the system's timezone if you call 'Calendar.getInstance()', so I changed it that way that you explicitly specify the timezone and Locale to be used. The latter is important if you e.g. want to get a date's week number where the rules differ in different regions of the world.

You can concat your parts into a String, and use a SimpleDateFormatter like:
int year = 2019;
int month = 1;
int day = 23;
String string = "" + year + "-" + month + "-" + day;
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(string);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
The example is for 2019 January 23.

Related

Get Date of Specific Week

I'm trying to get the start and end date of specific week of a month. However the date is incorrect. Can anyone identify what's the issue ?
public class DateUtils
{
getWeeklyDateList(2020,5, 3);
public static void getWeeklyDateList(int year, int month, int week)
{
Calendar calendar = Calendar.getInstance(Locale.getDefault());
// setting year, month, week
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.WEEK_OF_MONTH,week);
// setting day of week to first --> Sunday
calendar.set(Calendar.DAY_OF_WEEK, 1);
int year1 = calendar.get(Calendar.YEAR);
int month1 = calendar.get(Calendar.MONTH);
int day1 = calendar.get(Calendar.DAY_OF_MONTH);
// setting day of week to last --> Saturday
calendar.set(Calendar.DAY_OF_WEEK, 7);
int year7 = calendar.get(Calendar.YEAR);
int month7 = calendar.get(Calendar.MONTH);
int day7 = calendar.get(Calendar.DAY_OF_MONTH);
Log.e("date_start", String.valueOf(year1) + "-" + String.valueOf(month1) + "-" + String.valueOf(day1));
Log.e("date_end", String.valueOf(year7) + "-" + String.valueOf(month7) + "-" + String.valueOf(day7));
} }
java.time and ThreeTenABP
If you want to use java.time, the modern Java date and time API, it can be done with this simple method:
private static WeekFields wf = WeekFields.of(Locale.forLanguageTag("ne-NP"));
public static void getWeeklyDateList(int year, Month month, int week) {
LocalDate someDateInTheWeek = LocalDate.of(year, month, 10).with(wf.weekOfMonth(), week);
LocalDate start = someDateInTheWeek.with(wf.dayOfWeek(), 1);
LocalDate end = someDateInTheWeek.with(wf.dayOfWeek(), 7);
System.out.println("date_start: " + start);
System.out.println("date_end: " + end);
}
Trying it out with your example arguments:
getWeeklyDateList(2020, Month.JUNE, 3);
Output is:
date_start: 2020-06-14
date_end: 2020-06-20
How it works:
First, weeks are defined differently in different cultures. In Nepal (since you give Kathmandu, Nepal as your location) weeks start on Sunday and are numbered in a way where the 1st of the month is in week 1 of the month. To handle this week scheme I am initializing a WeekFields object for Nepalese culture.
LocalDate is the java.time class for a date without time of day. I don’t think it matters which day of the month I pick as a starting point; I took the 10th. From that date I get a date in the correct week, using the WeekFields object and the supplied week number. From there in turn I get the first and the last day of the week, again according to the Nepalese definition of weeks: from Sunday June 14 through Saturday June 20 2020.
What went wrong in your code I cannot tell. In any case the Calendar class you used is poorly designed and long outdated. It also default uses the default locale of the JVM for its week definition, which may have given you a different week scheme from what you wanted. A final point that may have confused you: Calendar unnaturally numbers months from 0 for January through 11 for December. So when you specified 5, you got June (not May). You printed out the month numbers of your result dates, which probably again printed 5 (not 6) for June.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Question: Why is January month 0 in Java Calendar?
Its because of this line,
calendar.set(Calendar.DAY_OF_WEEK, 1);
this can take month to previous month if week starts in previous one. If there is a month difference then this is the problem.

How to convert local time to LDAP timestamp in Java

I want to get two timestamps in LDAP format one has to be the beginning of the day and other has to be end of the day. It can be done by using Java 8 (using Joda-Time) but is there a way out using lower version like java 7.
This is the closest solution I found online, but I do not know how to get the timestamp of start of the day and end of the day. Additionally I need to check for 15 days back (start of the day end of the day from current system time)
To convert a Win32 filetime string to Date, use:
long fileTime = (Long.parseLong(inputDateString) / 10000L) - + 11644473600000L;
Date inputDate = new Date(fileTime);
To convert a Date to Win32 filetime, use:
long fileTime = (inputDate.getTime() + 11644473600000L) * 10000L;
String outputDate = Long.toString(fileTime);
e.g. 131220409910000000 will be converted to 2016/10/27 14-23-11 and vice versa
Check this url for a nice online epoch/filetime converter:
http://www.epochconverter.com/ldap
java.time and ThreeTen Backport
Instant ldapEpoch = Instant.parse("1601-01-01T00:00:00Z");
ZoneId zone = ZoneId.of("America/Port-au-Prince");
LocalDate date = LocalDate.now(zone);
Instant startOfDay = date.atStartOfDay(zone).toInstant();
Duration sinceLdapEpoch = Duration.between(ldapEpoch, startOfDay);
assert sinceLdapEpoch.getNano() == 0 : sinceLdapEpoch;
long ldapTimestamp = sinceLdapEpoch.getSeconds() * 10_000_000;
System.out.println(ldapTimestamp);
Output is (tested on jdk1.7.0_67):
132114384000000000
The start of the day differs from time zone to time zone. I have used America/Port-au-Prince as an example, you need to make your own pick. Use ZoneOffset.UTC if that is what you require.
For the end of the day use date.plusDays(1) instead of date in the same calculation. That will give you the first moment of the following day. Can you have the last moment of the current day instead? No, and you shouldn’t want to either. There is no last moment of a day. A day is a half-open time interval from the first moment of the day inclusive to the first moment of the next day exclusive. The best and the correct way to do in programming is to handle it as such (you may of course cheat and subtract 1 from the result you get to obtain the last possible LDAP timestamp of the day, not recommended).
I am using java.time, the modern Java date and time API. We don’t want to use Date or Calendar or other of the poorly designed and long outdated date and time classes in Java. java.time is so much nicer to work with.
Question: is there a way out using lower version like java 7?
Yes, java.time works nicely on Java 7. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
You could try the following:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c.clear();
c.set(2016, 4, 22); //your date
long time1= c.getTimeInMillis();
c.set(1601, 0, 1);
long time2= c.getTimeInMillis();
long ldap = (time1- time2) * 10000;

Why is Calendar value different?

I have to count the number of times depending on year, month, day, hour, minute.(second is unified to zero, I don't need second)
I chose HashMap as the data structure.
HashMap<Calendar,Integer> arr_time;
If there are same time(year,month,day,hour,minute) already, I want to increase the Integer, or add a new time(year,month,day,hour,minute).
Calendar calendar = Calendar.getInstance();
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0);
if(arr_time.containsKey(calendar)){
// increase Integer value
// ++1;
}else{
// add new time
// arr_time.put(calendar,1);
}
I thought it would recognize the same calendar if year, month, day, hour, and minute were the same.
But it was not.
What is the problem?
I didn't use "Date".
It's because, Android Devloper said like this.
Date(int year, int month, int date, int hrs, int min, int sec)
This constructor was deprecated in API level 1. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date, hrs, min, sec) or GregorianCalendar(year + 1900, month, date, hrs, min, sec).
Never use Calendar
The terrible Calendar class was supplanted by the java.time classes years ago, specifically ZonedDateTime.
Time zone
You are ignoring the crucial issue of time zone. A date and time-of-day have no real meaning until you provide the context of time zone (or offset-from-UTC). For example, noon is Europe/Paris is much later than noon in Asia/Tokyo and much earlier than noon in America/Montreal.
ZonedDateTime
Represent a date and time-of-day with time zone with the ZonedDateTime class.
ZoneID
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
truncatedTo
If you want to set the second and fractional second both to zero, truncate to the minute.
ZonedDateTime zdt = ZonedDateTime.now( z ).truncatedTo( ChronoUnit.MINUTES ) ; // Set the whole second and the fractional second both to zero.
LocalDateTime
If, for your counting purposes, you want to consider only the date with time-of-day while ignoring the time zone, extract a LocalDateTime. A LocalDateTime is simply a date with time-of-day, and lacks any concept of time zone or offset-from-UTC.
LocalDateTime ldt = zdt.toLocalDateTime() ;
Map ➙ SortedMap ➙ TreeMap
With a LocalDateTime in hand, you can do your counting. Make a Map where the key is a LocalDateTime, and the value is an Integer.
I imagine you will care about the sorted order of the date-time keys, so use a SortedMap. A TreeMap is one such implementation.
SortedMap< LocalDateTime , Integer > map = new TreeMap() ;
For each LocalDateTime, retrieve an Integer object from the Map. Increment the number count, and replace the old Integer object with a new one.
Using a Map has been covered many hundreds, if not thousands, of times already on Stack Overflow. So search if you need more discussion and examples of that.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - 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
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
java.time
Map<LocalDateTime, Integer> arr_time = new HashMap<>();
ZoneId zone = ZoneId.of("Antarctica/Vostok");
for (int i = 0; i < 10; i++) {
LocalDateTime now = LocalDateTime.now(zone).truncatedTo(ChronoUnit.MINUTES);
arr_time.compute(now, (ldt, oldCount) -> oldCount == null ? Integer.valueOf(1) : oldCount + 1);
TimeUnit.MILLISECONDS.sleep(103);
}
System.out.println(arr_time);
When I ran the code just now, I got:
{2019-02-20T13:42=10}
I recorded 10 times, sleeping in between to make sure they were not exactly the same. But because I truncated each to whole minutes, they all ended up being 2019-02-20T13:42 and were counted together.
To create a LocalDateTime from int variables:
int mYear = 2019;
int mMonth = Calendar.JANUARY;
int mDay = 31;
int mHour = 23;
int mMinute = 45;
LocalDateTime ldt = LocalDateTime.of(mYear, mMonth + 1, mDay, mHour, mMinute);
System.out.println(ldt);
2019-01-31T23:45
Since you used mMonth with Calendar, I assumed it was 0-based. LocalDateTime numbers months from 1, just like humans do, so I needed to add 1.
What went wrong in your code?
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0) sets year, month, day, hour, minute and second but is not setting the milliseconds. Since each Calendar object is created with the current time, the milliseconds will most often be different, so the even though you set the same values, the Calendar objects are still not equal.
That behaviour of the 6-arg set method surprises many and is just a minor point among the many points where the class is poorly designed. You shouldn’t use it. We’ve got java.time since 2014, so there’s really no reason to.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Instant.now equivalent to java.util.Date or Java 7

I have a system using Java 7 and I need to generate a date equivalente to Instant.now (Java 8).
For example, Instant.now().toString() generate a date like that:
"2018-12-19T12:32:46.816Z"
Using java.util.Date I have this date: "2018-12-19T10:38:13.892"
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat sdf;
sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
String text = sdf.format(date);
System.out.println(text);
I don't know if I can simply concatenate a "Z" at the end of this date.
Without "Z" another system that parse this date using Instant.parse throws the error:
java.time.format.DateTimeParseException: Text
'2018-12-19T10:38:13.892' could not be parsed at index 23
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1988)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1890)
at java.base/java.time.Instant.parse(Instant.java:395)
Z means UTC time zone, you can set the time zone to UTC and append Z mannually:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
ThreeTen Backport
java.time, the modern Java date and time API, has been backported. So just do as you would in Java 8:
String text = Instant.now().toString();
Running just now I got:
2018-12-19T13:37:37.186Z
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
The outdated SimpleDateFormat
If you don’t want to rely on an external dependency just until you move to Java 8 or higher, the (most) correct solution is this combination of pieces from the two other answers (one of them now deleted):
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX");
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String text = sdf.format(System.currentTimeMillis());
2018-12-19T13:37:37.285Z
It doesn’t always give the exact same string as Instant.toString, but it will give a string that Instant can parse in the other system. While Instant.toString() only prints as many decimals as necessary, the above SimpleDateFormat will print three decimals also when some of them are 0.
When the time zone of the formatter is UTC, format pattern letter (uppercase) X will print Z as “time zone” (really just an offset).
Links
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Oracle tutorial: Date Time explaining how to use java.time.

check if a date is equal independently of the year

I use javaSE 1.6 and I need to compare two dates and check if they are the same. this check needs to be independent of the year.
for example, i need to identify if today is the B-day of someone, and I need this code to be reused in the coming years.
so I need to perform the check, not on the year, not even on the day-of-the-year (issue with Leap year) but I can only rely on the day-of-the-month and the month number itself.
my input data, the birthday day of the person, it is in the Java class "Date"
is there any method of javaSE 1.6 that could help me?
I checked classes "Date" and "Calendar", but so far I couldn't find any hint to solve my issue.
ThreeTen Backport
public static MonthDay toMonthDay(Date utilDate) {
Instant inst = DateTimeUtils.toInstant(utilDate);
ZonedDateTime dateTime = inst.atZone(ZoneId.systemDefault());
return MonthDay.from(dateTime);
}
The MonthDay class of java.time is what you need, it’s a date without year, or conversely, a month and a day-of-month. Birthdays and other days to remember are the prime example for its use.
Like this:
Date birthday = // ...
Date today = new Date();
if (toMonthDay(today).equals(toMonthDay(birthday))) {
System.out.println("It’s her birthday");
} else {
System.out.println("It’s not her birthday");
}
On Java 6 you need to use the ThreeTen-Backport, the backport of java.time to Java 6 and 7.
I am hesitatingly using ZoneId.systemDefault() to use the JVM’s time zone setting for the conversion. On one hand the Date would normally assume this time zone; on the other hand this is fragile because the setting can be changed at any time from other parts of your program or other programs running in the same JVM. If you know better, by all means give a time zone like for example ZoneId.of("America/Adak")
If using Java 8 or later and the built-in java.time, the conversion is a little bit simpler:
ZonedDateTime dateTime = utilDate.toInstant().atZone(ZoneId.systemDefault());
return MonthDay.from(dateTime);
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
I found the way to call the Month and date-of-month in class Calendar.
here is my solution, I didn't find any other example on this topic, so I'll paste, maybe could help someone in the future.
if you have a more stylish solution, please let me know.
I'll be glad to learn :)
// date of the B-day 31st December
int month = Calendar.DECEMBER;
int date = 31;
boolean status = false;
// Class Date already filled with the date we wanna check.
Date beginDate;
Calendar c = Calendar.getInstance();
c.setTime(beginDate);
int dayOfMonthToCompare = c.get(Calendar.DAY_OF_MONTH);
int monthToCompare = c.get(Calendar.MONTH);
//perform check on day and Month
if(dayOfMonthToCompare == date && monthToCompare == month){
status = true;
}

Categories