I'm developing an application about bank holidays in many countries.
To find bank holidays dates in China I need to convert dates to Chinese system.
I have found many libraries in different languages, like :
this one : https://github.com/v5developer/maven-framework-project/blob/master/aimeizi-tutorials/src/main/java/net/aimeizi/tutorials/LunarCalendar.java that I transposed to Apex language
this one https://www.javascriptbank.com/javascript/time/Lunar_Calendar_script/amlich-hnd.js in js (it's for Vietnam but seems to work about the same)
or this one https://github.com/magiclen/JavaChineseCalendar/blob/master/src/main/java/org/magiclen/%E8%BE%B2%E6%9B%86/%E8%BE%B2%E6%9B%86.java
and more.
All of them use an array of numbers, with one number per year, like this one :
final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570,
0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0,
0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566,
0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4,
0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550,
0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950,
0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260,
0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0,
0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40,
0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3,
0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960,
0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0,
0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9,
0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0,
0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65,
0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0,
0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2,
0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };
used to calculate various numbers, like in
final private static int yearDays(int y) {
int i, sum = 348;
for (i = 0x8000; i > 0x8; i >>= 1) {
if ((lunarInfo[y - 1900] & i) != 0)
sum += 1;
}
return (sum + leapDays(y));
}
final private static int leapDays(int y) {
if (leapMonth(y) != 0) {
if ((lunarInfo[y - 1900] & 0x10000) != 0)
return 30;
else
return 29;
} else
return 0;
}
I've been searching in libraries comments, documentations, gerneral info about China, and I learnt a lot about the chinese calendar but couldn't find what these numbers are.... and where they come from.
It doesn't prevent me from using it but I like to understand what I code... Any explanations ?
Thanks
I finally came to understand that, at least for this code https://github.com/v5developer/maven-framework-project/blob/master/aimeizi-tutorials/src/main/java/net/aimeizi/tutorials/LunarCalendar.java, it's just a way to store data :
The data is encoded on 17 bits with :
bit 17 : number of days in leap month , 1=>30, 0=>29
bits 16 to 5 : number of days in each month, 0=>29, 1=>30
bits 4 to 1 : number of the leap month in the year in binary.
So 0x16554 (7th in the list, so year 1906) is 10110010101010100 in binary with a 17 bits length, which means :
10110010101010100 : There is a leap month, it's month 4
10110010101010100 : The leap month has 30 days
10110010101010100 : The 1st month has 29 days
10110010101010100 : The 2nd month has 30 days
...
10110010101010100 : The 12th month has 30 days
which can be checked here : https://www.asia-home.com//china/calendrier-chinois/year/1906.php
In other codes the meaning can vary but the idea is the same.
I am making a Alarm System for Mon, Tue, Wed, Thu, Fri Sat and Sun separate. Let's say i am setting an alarm for Tuesday than i need all Tuesdays of current Month and atleast for current year till the alarm is Off. I want to achieve it using moment.
I am using Package - 'moment-weekdaysin', this is not giving me proper result. It is giving me incorrect date.
code - moment().weekdaysInMonth('Monday')
I've not used moment-weedaysin before but it should share most of the same API as core moment. The code below will capture all Tuesday dates in the format of Month-Day-Year (MM-DD-YYY) from the current date til the end of the current year. You can change the parameter for any other days 1-7 (Monday-Sunday).
import moment from 'moment';
const getOccurrencesOfDayThisYear = (day = 1) => {
let startDate = moment();
const endOfYear = moment().endOf('year');
const extractedDates = [];
while (startDate.isBefore(endOfYear)) {
if (moment(startDate).day() == day) {
extractedDates.push(moment(startDate).format('MM-DD-YYYY'));
}
startDate = moment(startDate).add(1, 'days');
}
return extractedDates;
};
// 2 represents Tuesday; 1 being Monday and 7 being Sunday
getOccurrencesOfDayThisYear(2)
There might be a more sophisticated way of performing this through various moment methods.
As a little background: in October 1582 the Gregorian calendar was introduced to correct problems with the Julian calendar, which was in use until then. The Gregorian calendar specifies the length of a year more precisely, adds a new leap year calculation and removes 10 days from the Julian calendar on transition (moving from 4.Oct.1582 to 15.Oct.1582)
// Julian leap year calculation
((year % 4) == 0)
// Gregorian leap year calculation
((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)
To sum up all calendar days from 1 AD to 2001 AD I use:
#include <stdio.h>
int main( void)
{
int year;
int daysInYear;
int total;
total = 0;
for( year = 1; year <= 2001; year++)
{
//
daysInYear = 365;
if( year < 1582)
daysInYear += ((year % 4) == 0);
else
if( year > 1582)
daysInYear += ((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0);
else
daysInYear -= 10; // 1582 exactly
total += daysInYear;
printf( "%d: +%d = %d\n", year, daysInYear, total);
}
return( 0);
}
Now running this exhaustively over all years from 1 to 2000 gives this pastebin: https://pastebin.com/bR7hwNr1
The most interesting bits show that the leap year and day-skip calculation is correct and also produces the result:
1: +365 = 365
2: +365 = 730
3: +365 = 1095
4: +366 = 1461
...
100: +366 = 36525
...
400: +366 = 146100
...
1581: +365 = 577460
1582: +355 = 577815
1583: +365 = 578180
...
1900: +365 = 693962
...
1996: +366 = 729026
1997: +365 = 729391
1998: +365 = 729756
1999: +365 = 730121
2000: +366 = 730487
Now the question is this: the 1.1.2001 is at 730487 elapsed calendar days. Given the length of the year as defined by the Gregorian calendar as 365.2425, I would expect to see 2000*365.2425 = 730485 days. If one uses tropical days or solar days it would be 730484. But 740487 is clearly out of range.
Assuming that no-one miscounted any days in the Gregorian Calendar range, there are some extra days in the Julian Calendar, that don't match with the tropical days. But the Gregorian was created to correct the Julian calendar and I don't think they would have made that large an error in 1582.
This could be more a historical question than a programming question I would guess.
The goal of the Gregorian reform of the calendar was to reset the date of the northern hemisphere vernal equinox to March 21, and keep it there. This date was chosen because that was the approximate average date of the equinox at the time of the Council of Nicaea in AD 325. At the time of the council, the date of the equinox had slipped from about March 25 in AD 1.
For all the details read the book Gregorian Reform of the Calendar which is the proceedings of a conference held by the Vatican Observatory and published in 1983.
To clarify, when evaluating the Gregorian calendar compared to the Julian, using a mix of Julian and Gregorian dates incorporates the one-time correction of 10 days which was intended to correct for accumulated excess leap years from about AD 325 to AD 1582. If one wishes to use some start date other than AD 325, the entire calculation should use ONLY Gregorian dates or ONLY Julian dates.
I am very new to angular JS but since morning struggling with this.
I have a datepicker with "MM/yyyy" format, the date value returned here is first day of month.
i.e. February 1, 2017 but i want the date as February 28, 2017 i.e last day of month.
Just to update i am using moment function.
Please suggest some work around for the same!
I infer from your question that you are using momentjs.
This lib provides you with a built in function endof
const date = new Date(2017, 1) // 1st Feb
moment(date).endOf('month');
This should handle most cases directly including leap years
If you have a JavaScript Date instance d, you can simply use
const d = new Date(2017, 1) // 1st Feb
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.info(d.toLocaleString())
Now d will be the last day of the month.
Note: this easily handles year boundaries without any extra code. For example
const d = new Date(2017, 11) // 1st Dec
console.info('Before', d.toLocaleString())
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.info('After', d.toLocaleString())
You just need add 1 month to the date, and then substract 1 day. Here's an example:
// Let's suppose the date selected from the picker was February 1st, 2017
// Remember months in JS are zero-index based, so 0=Jan, 1=Feb, etc.
var selectedDate = new Date(2017, 1, 1);
var month = selectedDate.getMonth();
var year = selectedDate.getFullYear();
month ++;
if(month > 11){ // Last month number is 11 (December)
month = 0; // January
year ++;
}
var oneMonthAheadDate = new Date(year, month, 1);
var lastDayOfSelectedMonthDate = new Date(oneMonthAheadDate.getTime() - (1000 * 3600 * 24)); // We substract 1 day (1000 ms x 3600 secs in an hour x 24 hours in a day)
Your needed date will be in lastDayOfSelectedMonthDate
The prompt is:
Implement a function that reads in a string containing a textual description of a calendar date and that prints out the corresponding day of the week (Monday–Sunday). The two valid input formats for this function are:
mm/dd/yyyy
Example: 03/04/2014 Output: Tuesday
Month dd, yyyy
Example: March 04, 2014 Output: Tuesday
where dd is the numeric day, mm is the numeric month, yyyy is the year and Month is the name of the month. All days and months are specified using two digits (i.e. for March, use 03 instead of 3). In the second valid format, there is a single space between Month and dd and between dd, and yyyy.
In order to receive full credit on this task, your program should print out the correct day of the week for any input in a correct format.
The code I have so far is able to give me the number of the day of the year that I input but from there I don't know what to do so that it will give me the day of the week because each year starts from a different weekday to begin with.
#include<stdio.h>
int main() {
int month, day, year, dm, dn, leap;
printf("enter the month:");
scanf("%d",&month);
printf("enter the day:");
scanf("%d",&day);
printf("enter the year:");
scanf("%d",&year);
if((year%100 == 0 && year%400 == 0) || (year%4==0)) {
if(month==1)
dm=0;
if(month==2)
dm=31;
if(month==3)
dm=60;
if(month==4)
dm=91;
if(month==5)
dm=121;
if(month==6)
dm=152;
if(month==7)
dm=182;
if(month==8)
dm=213;
if(month==9)
dm=244;
if(month==10)
dm=274;
if(month==11)
dm=305;
if(month==12)
dm=335;
}
else {
if(month==1)
dm=0;
if(month==2)
dm=31;
if(month==3)
dm=59;
if(month==4)
dm=90;
if(month==5)
dm=120;
if(month==6)
dm=151;
if(month==7)
dm=181;
if(month==8)
dm=212;
if(month==9)
dm=243;
if(month==10)
dm=273;
if(month==11)
dm=303;
if(month==12)
dm=334;
}
dn = dm+day;
printf("the day number is :%d",dn);
return 0;
}