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'm trying to map the max number of consecutive days with rain <1 mm in Google Earth Engine.
This is the link to the code
https://code.earthengine.google.com/22b5c20d2700a2ffb5989f892838ac58
First I reclassify the collection with 0 if rain <=1 and 1 if >1.
Then I run the code that should count the days of the longest dry period, but it is able to do so only if the dry period reach the end of the time period.
For instance if I am looking for the longest dry period in 4 days timestep i get the following series:
rain days 1 2 3 4 output
0,0,1,1 = 0 dry days
0,1,0,0 = 2 dry days
0 = rain<=1 and
1 = rain>1 (as per the first step)
Does anyone can help in solving this?
Thanks
I don't think you were far off in your code that you provided. To keep track of the dry spells you have to use .iterate(). I took a stab at your application in a little different way where instead of classifying the data before the iteration, I calculate which pixels are dry each day and carry over the accumulated days that a pixel is dry, otherwise it is set to zero:
// DATA
var collection = ee.ImageCollection("UCSB-CHG/CHIRPS/DAILY");
// Define time range
var startyear = 2000;
var endyear = 2017;
var startmonth = 1;
var endmonth = 12;
// Set date in ee date format
var startdate = ee.Date.fromYMD(startyear,startmonth,1);
var enddate = ee.Date.fromYMD(endyear,endmonth,31);
// Filter data
var datain_t = collection.filterDate(startdate, enddate)
.filter(ee.Filter.calendarRange(startmonth,endmonth, 'month'))
.select("precipitation").map(function(img){
return img.addBands(ee.Image.constant(0).uint8().rename('counter'));
})
.sort('system:time_start');
// // START
var dataset = datain_t
.filterDate("2016-08-01","2016-08-30")
.sort('system:time_start:');
print(dataset,"dataset");
var precipThresh = 1; // mm
function drySpells(img, list){
// get previous image
var prev = ee.Image(ee.List(list).get(-1));
// find areas gt precipitation threshold (gt==0, lt==1)
var dry = img.select('precipitation').lt(precipThresh);
// add previous day counter to today's counter
var accum = prev.select('counter').add(dry).rename('counter');
// create a result image for iteration
// precip < thresh will equal the accumulation of counters
// otherwise it will equal zero
var out = img.select('precipitation').addBands(
img.select('counter').where(dry.eq(1),accum)
).uint8();
return ee.List(list).add(out);
}
// create first image for iteration
var first = ee.List([ee.Image(dataset.first())]);
// apply dry speall iteration function
var maxDrySpell = ee.ImageCollection.fromImages(
dataset.iterate(drySpells,first)
).max(); // get the max value
// display results
Map.addLayer(maxDrySpell.select('counter'),{min:0,max:30,palette:'#9ecae1,#ffffff,#ffeda0,#feb24c,#f03b20'},'Max Dry Spells');
Here is the link to the code: https://code.earthengine.google.com/80b4c0f7e82a5f0da316af1d2a55dd59
Don't try to run this analysis for too long of a time period or Earth Engine will give an error. I hope this helps!
Basically I'm attempting a question on how to compute fee. However, my code is extremely long. I ended up using a heck tons of 'if' and 'else' for my code. I was wondering if there is any better way on approaching this question.
I initially attempted to use loops to keep stacking the fee but I face a problem when my time cross the critical juncture. I added time to TimeIn along with my fees, but as it crosses the 7am mark, I need to reset it back to 7am so that my fees will be charge properly. And that was when I gave up when my code became very long too.
Eg. loop adds from 0630 to 0730, fees are properly increased, the first 30 minutes of 0700 will be skipped and fees are wrongly charged.
The question I attempted:
Mr. Wu has been going to work every day by taxi for many years. However, the taxi fare has been increasing rather quickly in recent years. Therefore, he is considering driving to work instead.
One of the costs for driving is the parking fee. The parking rates of the car park at Mr. Wu’s workplace are as shown in the table below.
Weekday Saturday Sunday
4am ~ 7am $2.00 per hour $2.50 per hour $5
7am ~ 6pm $1.20 per 30 minute $1.50 per 30 minutes per
6pm ~ midnight $5.00 per entry $7.00 per entry entry
Special note:
1. The car park opens at 4am and closes at midnight. All vehicles must leave
by midnight.
2. There is a grace period of 10 minutes on any day (i.e., it is completely
free to park for 10 minutes or less regardless of day and time.)
3. There is a 10% surcharge for parking more than 10 hours on a weekday and
20% for Saturday. There is no surcharge for Sunday.
4. There is an additional $3.00 fee for exiting after 10pm on any day.
(Surcharge is not applicable on this fee.)
Your program should read in one integer, which is an integer between 1 and 7
representing the day of the week (1 being Monday and 7 being Sunday). It should also
read in two numbers representing the time-in and time-out in 24-hour format. It
should then calculate and display the parking fee (with two decimal places).
You may assume that the inputs are valid (i.e., the day is within the specified range,
both time-in and time-out are between 4am and midnight in 24-hour format, and timeout
is no earlier than time-in).
My extremely long code:
#include <stdio.h>
#include <math.h>
double computeFee(int, int, int);
int main(void){
int day, timeIn, timeOut;
scanf("%d %d %d", &day, &timeIn, &timeOut);
printf("Enter day: %d\n", day);
printf("Enter time-in: %d\n", timeIn);
printf("Enter time-out: %d\n", timeOut);
printf("Parking fee is $%.2lf\n", computeFee(day, timeIn, timeOut));
return 0;
}
double computeFee(int day, int timeIn, int timeOut){
double fee = 0;
double TimeIn, TimeOut;
TimeIn = 60*(floor(timeIn/100)) + (timeIn%100);
TimeOut = (60*(floor(timeOut/100)) + (timeOut%100));
if((day>=1)&&(day<=5)){
if(TimeIn<420){
if(TimeOut<420){
fee += 2*ceil((TimeOut - TimeIn)/60);
}
else{
fee += 6;
if(TimeOut>=1080){
fee += 31.4;
}
else{
fee += 1.2*ceil((TimeOut - 420)/30);
}
}
}
if(TimeIn>=420){
if(TimeIn>=1080){
fee = 5;
}
else{
if(TimeOut>=1080){
fee += (1.2*ceil((1080 - TimeIn)/30) + 5);
}
else{
fee += (1.2*ceil((TimeOut - TimeIn)/30));
}
}
}
if((TimeOut-TimeIn)>=600){
fee *= 1.1;
}
}
if(day == 6){
if(TimeIn<420){
if(TimeOut<420){
fee += (2.5*ceil((TimeOut - TimeIn)/60));
}
else{
fee += 7.5;
if(TimeOut>=1080){
fee += 40;
}
else{
fee += (1.5*ceil((TimeOut - 420)/30));
}
}
}
if(TimeIn>=420){
if(TimeIn>=1080){
fee = 7;
}
else{
if(TimeOut>=1080){
fee += (1.5*ceil((1080 - TimeIn)/30) + 7);
}
else{
fee += (1.5*ceil((TimeOut - TimeIn)/30));
}
}
}
if((TimeOut-TimeIn)>=600){
fee *= 1.2;
}
}
if(day == 7){
fee = 5;
}
if((timeOut/100)>=22){
fee += 3;
}
if((timeOut - timeIn)<=10){
fee = 0;
}
return fee;
}
Examples on how fees are calculated:
Example 1: Tuesday, 4:29am to 7:50am.
• 4:29am to 7am is charged as 3 1-hour slots: $2.00 * 3 = $6.00
• 7am to 7:50am is charged as 2 30-minute slots: $1.20 * 2 = $2.40
• Total fee = $6.00 + $2.40 = $8.40
Example 2: Saturday, 7:01am to 7:49pm.
• 7:01am to 6pm is charged as 22 30-minute slots: $1.50 * 22 = $33.00
• 6pm to 7:49pm is charged as one entry: $7.00
• 20% Surcharge for parking more than 10 hours: ($33.00 + $7.00) * 20% =
$8.00
• Total fee = $33.00 + $7.00 + $8.00 = $48.00
Example 3: Sunday, 3pm to 10:01pm.
• 3pm to 10:01pm is charged as one entry: $5.00
• Additional fee for exiting after 10pm: $3.00
• Total fee = $5.00 + $3.00 = $8.00
Example 4: Thursday, 11:49pm to 11:59pm.
• Grace period
• Total fee = $0.00
Example 5: Monday, 12pm to 10:01pm.
• 12pm to 6pm is charged as 12 30-minute slots: $1.20 * 12 = $14.40
• 6pm to 10:01pm is charged as one entry: $5.00
• 10% Surcharge for parking more than 10 hours: ($14.40 + $5.00) * 10% =
$1.94
• Additional fee for exiting after 10pm: $3.00
• Total fee = $14.40 + $5.00 + $1.94 + $3.00 = $24.34
Thanks for reading my long question. And thanks in advance for the help.
note: I havent learn arrays and anything beyond that. Only learn loops and selection statement so far(reading K&R programming tutorial, until chapter 17, using Online GeekforGeek as compiler). However, I will still greatly appreciate solutions using other methods.
cost = int(input("Enter the cost:\n"))
payment = int(input("Deposit a coin or note:\n"))
if payment >= cost:
change = payment - cost
print (change)
elif payment < cost:
while payment < cost:
payment = int(input("Deposit a coin or note:\n"))
change = cost - payment
print (change)
break
I basically want the value of "change".
The above was wrong because it wasn't 'storing' the value of the first payment if it was less than cost, realized my bad mistake.
cost = int(input("Enter the cost:\n"))
payment = 0
while payment < cost:
firstpayment = int(input("Deposit a coin or note:\n"))
payment = payment + firstpayment
if payment > cost:
change = payment - cost
print ("Your change is: $",change)
The loop condition says:
while payment< cost:
So, the loop automatically exists when payment becomes more than cost. So an easier approach will be,
while payment<cost:
#do something
change = payment-cost
Coz, when the loop ends, we know that payment should be >= cost...
The prompt is:
Implement a function that reads in a string containing a textual description of a cal- endar 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.
So as of right now i am able to get the correct days for every single day except in the years 2005 2009 2013 2017 etc etc... they are always a day behind, i notice that its going by a trend of every 4 years the days end up 1 day behind. Im not sure whats wrong. is it cause my method of using 365.25 as each year is wrong?
My code:
#include<stdio.h>
int main()
{
int month,day1,day2,totdays,year,dm,dn,leap,rmd;
printf(" ");
scanf("%d/%d/%d",&month,&day1,&year);
if(((year%4==0) && (year%100!=0)) || (year%400==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=304;
if(month==12)
dm=334;
}
day2=(year-1970)*(365.25);
dn=dm+day1;
totdays=day2+dn;
rmd=totdays%7;
if(rmd==5)
{
printf("Monday \n");
}
if(rmd==6)
{
printf("Tuesday \n");
}
if(rmd==0)
{
printf("Wednesday \n");
}
if(rmd==1)
{
printf("Thursday \n");
}
if(rmd==2)
{
printf("Friday \n");
}
if(rmd==3)
{
printf("Saturday \n");
}
if(rmd==4)
{
printf("Sunday \n");
}
return 0;
}
1969 wasn't a leap year, 1972 was. When you do
day2=(year-1970)*(365.25);
to discover how many days off January 1st of year year is, you'll count
0 days for '70
365.25 days for '71
730.5 days for '72
1095.75 days for '73
1461 days for '74
The fractional portion of the floating point calculation is truncated, so day2 isn't going to count the extra day from 02/29/1972 until 01/01/1974, instead of 01/01/1973 as it should.
Put another way, you are making the assumption that 1970 was the first year after a leap year, so a leap day won't be counted until four years later.
The day2 calculation won't work. There are 1461 days in every four year period. First you need to compute how many 4 year periods have passed. Then figure out how many days there were to the beginning of the specified year, similar to what you did for the months.
The year%100 and year%400 exceptions add a little complexity, but fortunately the year 2000 was a leap year, so the first time you have to deal with that little wrinkle is the year 2100.