123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
|
/*******************************************************************************
copyright: Copyright (c) 2005 John Chapman. All rights reserved
license: BSD style: $(LICENSE)
version: Mid 2005: Initial release
Apr 2007: reshaped
author: John Chapman, Kris
******************************************************************************/
module tango.time.chrono.Hijri;
private import tango.time.chrono.Calendar;
/**
* $(ANCHOR _Hijri)
* Represents the Hijri calendar.
*/
public class Hijri : Calendar {
private enum uint[] DAYS_TO_MONTH = [ 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 ];
/**
* Represents the current era.
*/
public enum uint HIJRI_ERA = 1;
/**
* Overridden. Returns a Time value set to the specified date and time in the specified _era.
* Params:
* year = An integer representing the _year.
* month = An integer representing the _month.
* day = An integer representing the _day.
* hour = An integer representing the _hour.
* minute = An integer representing the _minute.
* second = An integer representing the _second.
* millisecond = An integer representing the _millisecond.
* era = An integer representing the _era.
* Returns: A Time set to the specified date and time.
*/
public override const Time toTime(uint year, uint month, uint day, uint hour, uint minute, uint second, uint millisecond, uint era) {
return Time((daysSinceJan1(year, month, day) - 1) * TimeSpan.TicksPerDay + getTimeTicks(hour, minute, second)) + TimeSpan.fromMillis(millisecond);
}
/**
* Overridden. Returns the day of the week in the specified Time.
* Params: time = A Time value.
* Returns: A DayOfWeek value representing the day of the week of time.
*/
public override const DayOfWeek getDayOfWeek(const(Time) time) {
return cast(DayOfWeek) (cast(uint) (time.ticks / TimeSpan.TicksPerDay + 1) % 7);
}
/**
* Overridden. Returns the day of the month in the specified Time.
* Params: time = A Time value.
* Returns: An integer representing the day of the month of time.
*/
public override const uint getDayOfMonth(const(Time) time) {
return extractPart(time.ticks, DatePart.Day);
}
/**
* Overridden. Returns the day of the year in the specified Time.
* Params: time = A Time value.
* Returns: An integer representing the day of the year of time.
*/
public override const uint getDayOfYear(const(Time) time) {
return extractPart(time.ticks, DatePart.DayOfYear);
}
/**
* Overridden. Returns the day of the year in the specified Time.
* Params: time = A Time value.
* Returns: An integer representing the day of the year of time.
*/
public override const uint getMonth(const(Time) time) {
return extractPart(time.ticks, DatePart.Month);
}
/**
* Overridden. Returns the year in the specified Time.
* Params: time = A Time value.
* Returns: An integer representing the year in time.
*/
public override const uint getYear(const(Time) time) {
return extractPart(time.ticks, DatePart.Year);
}
/**
* Overridden. Returns the era in the specified Time.
* Params: time = A Time value.
* Returns: An integer representing the ear in time.
*/
public override const uint getEra(const(Time) time) {
return HIJRI_ERA;
}
/**
* Overridden. Returns the number of days in the specified _year and _month of the specified _era.
* Params:
* year = An integer representing the _year.
* month = An integer representing the _month.
* era = An integer representing the _era.
* Returns: The number of days in the specified _year and _month of the specified _era.
*/
public override const uint getDaysInMonth(uint year, uint month, uint era) {
if (month == 12)
return isLeapYear(year, CURRENT_ERA) ? 30 : 29;
return (month % 2 == 1) ? 30 : 29;
}
/**
* Overridden. Returns the number of days in the specified _year of the specified _era.
* Params:
* year = An integer representing the _year.
* era = An integer representing the _era.
* Returns: The number of days in the specified _year in the specified _era.
*/
public override const uint getDaysInYear(uint year, uint era) {
return isLeapYear(year, era) ? 355 : 354;
}
/**
* Overridden. Returns the number of months in the specified _year of the specified _era.
* Params:
* year = An integer representing the _year.
* era = An integer representing the _era.
* Returns: The number of months in the specified _year in the specified _era.
*/
public override const uint getMonthsInYear(uint year, uint era) {
return 12;
}
/**
* Overridden. Indicates whether the specified _year in the specified _era is a leap _year.
* Params: year = An integer representing the _year.
* Params: era = An integer representing the _era.
* Returns: true is the specified _year is a leap _year; otherwise, false.
*/
public override const bool isLeapYear(uint year, uint era) {
return (14 + 11 * year) % 30 < 11;
}
/**
* $(I Property.) Overridden. Retrieves the list of eras in the current calendar.
* Returns: An integer array representing the eras in the current calendar.
*/
public override const uint[] eras() {
auto tmp = [HIJRI_ERA];
return tmp.dup;
}
/**
* $(I Property.) Overridden. Retrieves the identifier associated with the current calendar.
* Returns: An integer representing the identifier of the current calendar.
*/
public override const uint id() {
return HIJRI;
}
private const long daysToYear(uint year) {
int cycle = ((year - 1) / 30) * 30;
int remaining = year - cycle - 1;
long days = ((cycle * 10631L) / 30L) + 227013L;
while (remaining > 0) {
days += 354 + (isLeapYear(remaining, CURRENT_ERA) ? 1 : 0);
remaining--;
}
return days;
}
private const long daysSinceJan1(uint year, uint month, uint day) {
return cast(long)(daysToYear(year) + DAYS_TO_MONTH[month - 1] + day);
}
private const int extractPart(long ticks, DatePart part) {
long days = TimeSpan(ticks).days + 1;
int year = cast(int)(((days - 227013) * 30) / 10631) + 1;
long daysUpToYear = daysToYear(year);
long daysInYear = getDaysInYear(year, CURRENT_ERA);
if (days < daysUpToYear) {
daysUpToYear -= daysInYear;
year--;
}
else if (days == daysUpToYear) {
year--;
daysUpToYear -= getDaysInYear(year, CURRENT_ERA);
}
else if (days > daysUpToYear + daysInYear) {
daysUpToYear += daysInYear;
year++;
}
if (part == DatePart.Year)
return year;
days -= daysUpToYear;
if (part == DatePart.DayOfYear)
return cast(int)days;
int month = 1;
while (month <= 12 && days > DAYS_TO_MONTH[month - 1])
month++;
month--;
if (part == DatePart.Month)
return month;
return cast(int)(days - DAYS_TO_MONTH[month - 1]);
}
}
|