Java tutorial
//package com.java2s; /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class Main { /** * Given a calendar (possibly containing only a day of the year), returns the earliest possible * anniversary of the date that is equal to or after the current point in time if the date * does not contain a year, or the date converted to the local time zone (if the date contains * a year. * * @param target The date we wish to convert(in the UTC time zone). * @return If date does not contain a year (year < 1900), returns the next earliest anniversary * that is after the current point in time (in the local time zone). Otherwise, returns the * adjusted Date in the local time zone. */ public static Date getNextAnnualDate(Calendar target) { final Calendar today = Calendar.getInstance(); today.setTime(new Date()); // Round the current time to the exact start of today so that when we compare // today against the target date, both dates are set to exactly 0000H. today.set(Calendar.HOUR_OF_DAY, 0); today.set(Calendar.MINUTE, 0); today.set(Calendar.SECOND, 0); today.set(Calendar.MILLISECOND, 0); final boolean isYearSet = isYearSet(target); final int targetYear = target.get(Calendar.YEAR); final int targetMonth = target.get(Calendar.MONTH); final int targetDay = target.get(Calendar.DAY_OF_MONTH); final boolean isFeb29 = (targetMonth == Calendar.FEBRUARY && targetDay == 29); final GregorianCalendar anniversary = new GregorianCalendar(); // Convert from the UTC date to the local date. Set the year to today's year if the // there is no provided year (targetYear < 1900) anniversary.set(!isYearSet ? today.get(Calendar.YEAR) : targetYear, targetMonth, targetDay); // If the anniversary's date is before the start of today and there is no year set, // increment the year by 1 so that the returned date is always equal to or greater than // today. If the day is a leap year, keep going until we get the next leap year anniversary // Otherwise if there is already a year set, simply return the exact date. if (!isYearSet) { int anniversaryYear = today.get(Calendar.YEAR); if (anniversary.before(today) || (isFeb29 && !anniversary.isLeapYear(anniversaryYear))) { // If the target date is not Feb 29, then set the anniversary to the next year. // Otherwise, keep going until we find the next leap year (this is not guaranteed // to be in 4 years time). do { anniversaryYear += 1; } while (isFeb29 && !anniversary.isLeapYear(anniversaryYear)); anniversary.set(anniversaryYear, targetMonth, targetDay); } } return anniversary.getTime(); } public static boolean isYearSet(Calendar cal) { // use the Calendar.YEAR field to track whether or not the year is set instead of // Calendar.isSet() because doing Calendar.get() causes Calendar.isSet() to become // true irregardless of what the previous value was return cal.get(Calendar.YEAR) > 1; } }