epoch in seconds to MJD conversion in C - c

I wanted to convert the given time in epoch format to MJD (Modified Julian Day). But not getting exact MJD equivalent. I think missing some offset value.
#include <stdio.h>
#include <time.h>
#include <memory.h>
int get_mjd (int Y, int M, int D)
{
int L = 0, MJD = 0;
if ((M == 1) || (M == 2))
L = 1;
MJD = 14956 + D + (int)((Y - L) * 365.25) +
(int)((M + 1 + L * 12) * 30.60001);
return MJD;
}
int main(){
time_t start;
int mjd;
struct tm start_tm;
start = 1442286867; // Tue, 15 Sep 2015 03:14:27 GMT
memcpy(&start_tm, localtime(&start),sizeof(struct tm));
printf("year:%d\tmonth: %d\tday: %d\n",start_tm.tm_year,start_tm.tm_mon,start_tm.tm_mday);
mjd = get_mjd(start_tm.tm_year,start_tm.tm_mon, start_tm.tm_mday);
printf("mjd: %d\n",mjd);
return 0;
}
Output:
year:115 month: 8 day: 15
mjd: 57249
Expected mjd should is 57280
Please let me know what could be missing here.

If you don't need the date broken down into Gregorian calendar year/month/day values, there's a much simpler way.
double mjd(time_t epoch_time)
{
return epoch_time / 86400.0 + 40587;
}
The value 40587 is the number of days between the MJD epoch (1858-11-17) and the Unix epoch (1970-01-01), and 86400 is the number of seconds in a day.

Ref Modified Julian Day: Days since November 17, 1858
get_mjd() oddly references Y as years from 1900, yet M in the traditional 1 = January, 2 = February, etc.
get_mjd() works for years in the range 1898 to 2099, but fails outside that.
// For years from 1900, limited range
int get_mjd (int Y, int M, int D) {
int L = 0, MJD = 0;
if ((M == 1) || (M == 2))
L = 1;
MJD = 14956 + D + (int)((Y - L) * 365.25) +
(int)((M + 1 + L * 12) * 30.60001);
return MJD;
}
The following works over a much larger range or the Gregorian calendar.
M,D not limited to their usual range and does not need floating point math.
#define DaysPer400Years (365L*400 + 97)
#define DaysPer100Years (365L*100 + 24)
#define DaysPer4Years (365*4 + 1)
#define DaysPer1Year 365
#define MonthsPerYear 12
#define MonthsPer400Years (12*400)
#define MonthMarch 3
#define mjdOffset (678881 /* Epoch Nov 17, 1858 */)
static const short DaysMarch1ToBeginingOfMonth[12] = {
0,
31,
31 + 30,
31 + 30 + 31,
31 + 30 + 31 + 30,
31 + 30 + 31 + 30 + 31,
31 + 30 + 31 + 30 + 31 + 31,
31 + 30 + 31 + 30 + 31 + 31 + 30,
31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 31 };
int ymd_to_mjd_x(int year, int month, int day) {
year += month / MonthsPerYear;
month %= MonthsPerYear;
// Adjust for month/year to Mar... Feb
while (month < MonthMarch) {
month += MonthsPerYear; // Months per year
year--;
}
int d = (year / 400) * DaysPer400Years;
int y400 = (int) (year % 400);
d += (y400 / 100) * DaysPer100Years;
int y100 = y400 % 100;
d += (y100 / 4) * DaysPer4Years;
int y4 = y100 % 4;
d += y4 * DaysPer1Year;
d += DaysMarch1ToBeginingOfMonth[month - MonthMarch];
d += day;
// November 17, 1858 == MJD 0
d--;
d -= mjdOffset;
return d;
}

It was yet another off by one error. struct tm returns month with range 0-11.
I needed to +1 to tm_mon before using get_mjd(). Now it works!

Related

return the day of the week with day, month, year and first of January provided?

I have the C99 as follow:
int dayOfWeek(int day, int month, int year, int firstJan);
The first parameter, day, provides the day of interest − range from 1 to 31 (inclusive). The second parameter, month, provides the month of interest − range from 1 to 12 (inclusive). The third parameter, year, provides the year of interest − any integer value of 1970 or greater. The fourth parameter, firstJan, indicates the day of the week on which the first of January falls in the provided year.
The function will return the day of the week on which the indicated date falls. For example, the call:
dayOfWeek(13, 11, 2017, 0);
will return the integer 1 (representing Monday).
How can I approach the solution? Its permitted values are 0 (representing Sunday), 1 (representing Monday), and so on, up to 6 (representing Saturday). Code has been edit:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int dayOfweek(int day, int month, int year, int firstJan)
5 {
6 int mth[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
7 int mth_leap[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
8
9 if(year <1970 || month < 1 || month > 12 || day < 1 || day > 31 || firstJan < 0 || firstJan > 6 ){
10 printf("invalid input");
11 //return -1;
12 }
13
14 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)){
15 day = mth_leap[month - 1] + day ;
16 }else{
17 day = mth[month - 1] + day;
18 }
19
20 int dow = (day - firstJan + 7)%7;
21 printf("Day of week is %i.\n", dow);
22 //return 1;
23
24 }
Day of the week is found simply with mktime().
The mktime function
On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time,
#include <time.h>
int dayOfWeek(int day, int month, int year, int /*firstJan*/) {
// struct tm members domain are: years from 1900, and months since January
// Important to set tm_isdst = -1 to let the function determine dst setting.
struct tm ymd = { .tm_year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_isdst = -1);
time_t t = mktime(&ymd); // this will fill in .tm_wday
if (t == -1) return -1; // Failed to find a valid calender time (and day-of-the-week)
return ymd.tm_wday;
}
How can I approach the solution?
Yet OP has a function that provides the day-of-the-week for Jan 1st.
Some pseudo code for that approach:
int dayOfWeek(int day, int month, int year, int firstJan) {
days_since_jan1 = table[month] + day;
if (month > Feb and isleap(year)) days_since_jan1++;
dow = (days_since_jan1 - firstJan + 7)%7
}

Calendar Programming Project in C. Too complicated for this newbie [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
void main()
{
int numdays, month, day, year = 1;
while (year > 0)`enter code here`
{
printf("Enter Month: ");
scanf("%d", &month);
printf("Enter Day: ");
scanf("%d", &day);
printf("Enter Year: ");
scanf("%d", &year);
numdays = ((year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400)); // how many days including exceptions
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //check if leapyear
{
if (month = 1) // January
numdays = numdays;
if (month = 2) // February
numdays = numdays + 31;
if (month = 3) // March
numdays = numdays + 28 + 31 + 1;
if (month = 4) // April
numdays = numdays + 31 + 28 + 31 + 1;
if (month = 5) // May
numdays = numdays + 30 + 31 + 28 + 31 + 1;
if (month = 6) // June
numdays = numdays + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 7) // July
numdays = numdays + 30 + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 8) // August
numdays = numdays + 31 + 30 + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 9) // September
numdays = numdays + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 10) // October
numdays = numdays + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 11) // November
numdays = numdays + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + 1;
if (month = 12) // December
numdays = numdays + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31 + 1;
}
else
{
if (month = 1) // January
numdays = numdays;
if (month = 2) // February
numdays = numdays + 31;
if (month = 3) // March
numdays = numdays + 28 + 31;
if (month = 4) // April
numdays = numdays + 31 + 28 + 31;
if (month = 5) // May
numdays = numdays + 30 + 31 + 28 + 31;
if (month = 6) // June
numdays = numdays + 31 + 30 + 31 + 28 + 31;
if (month = 7) // July
numdays = numdays + 30 + 31 + 30 + 31 + 28 + 31;
if (month = 8) // August
numdays = numdays + 31 + 30 + 31 + 30 + 31 + 28 + 31;
if (month = 9) // September
numdays = numdays + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31;
if (month = 10) // October
numdays = numdays + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31;
if (month = 11) // November
numdays = numdays + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31;
if (month = 12) // December
numdays = numdays + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31;
{
printf("%d %d %d\n", month, day, year);
}
int daycode = numdays % 7;
switch (daycode)
{
case 0:
printf("Sunday\n");
break;
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
case 4:
printf("Thursday\n");
break;
case 5:
printf("Friday\n");
break;
case 6:
printf("Saturday\n");
break;
default: printf("unexpected error (daycode case) daycode = %d", daycode);
break;`enter code here`
}
}
}
}
What I need to do is get the output to read what the day would be on the given date input by the user. However, I don't understand why my month is being locked at 12 for input. Any help is appreciated.
As mentioned in a comment by MrPickles, the main problem is that you are mixing up the assignment operator = with the comparison operator ==. The former (=) sets the variable on the left to whatever is on the right, while == checks if the right hand and left hand sides are equal. Your last if statement is setting month to 12 instead of checking if it's 12.
Another big problem is that your code to print out the solution is inside your else statement, so it doesn't run at all if it's a leap year. Make sure to move it out.
Finally, you never actually use the day of the month in your code. You need to put in something like numdays+=day;.
Other than that, you could make the code much shorter, but I think it's right besides that.

Karatsuba Algorithm: splitting strings

I am trying to implement the Karatsuba algorithm in C.
I work with char strings (which are digits in a certain base), and although I think I have understood most of the Karatsuba algorithm, I do not get where I should split the strings to multiply.
For example, where should I cut 123 * 123, and where should I cut 123 * 12?
I can't get to a solution that works with both these calculations.
I tried to cut it in half and flooring the result when the number if odd, but it did not work, and ceiling does not work too.
Any clue?
Let a, b, c, and d be the parts of the strings.
Let's try with 123 * 12
First try (a = 1, b = 23, c = 1, d = 2) (fail)
z0 = a * c = 1
z1 = b * d = 46
z2 = (a + b) * (c + d) - z0 - z1 = 24 * 3 - 1 - 46 = 72 - 1 - 46 = 25
z0_padded = 100
z2_padded = 250
z0_padded + z1 + z2_padded = 100 + 46 + 250 = 396 != 123 * 12
Second try (a = 12, b = 3, c = 12, d = 0) (fail)
z0 = 144
z1 = 0
z2 = 15 * 12 - z1 - z0 = 180 - 144 = 36
z0_padded = 14400
z2_padded = 360
z0_padded + z1 + z2_padded = 14760 != 1476
Third try (a = 12, b = 3, c = 0, d = 12) (success)
z0 = 0
z1 = 36
z2 = 15 * 12 - z0 - z1 = 144
z0_padded = 0
z2_padded = 1440
z0_padded + z1 + z2_padded = 1476 == 1476
Let's try with 123 * 123
First try (a = 1, b = 23, c = 1, d = 23) (fail)
z0 = 1
z1 = 23 * 23 = 529
z2 = 24 * 24 - z0 - z1 = 46
z0_padded = 100
z2_padded = 460
z0_padded + z1 + z2_padded = 561 != 15129
Second try (a = 12, b = 3, c = 12, d = 3) (success)
z0 = 12 * 12 = 144
z1 = 3 * 3 = 9
z2 = 15 * 15 - z0 - z1 = 72
z0_padded = 14400
z2_padded = 720
z0_padded + z1 + z2_padded = 15129 == 15129
Third try (a = 12, b = 3, c = 1, d = 23) (fail)
z0 = 12
z1 = 3 * 23 = 69
z2 = 15 * 24 - z0 - z1 = 279
z0_padded = 1200
z2_padded = 2799
z0_padded + z1 = z2_padded = 4068 != 15129
Here, I do not get where I messed this up. Note that my padding method adds n zeroes at the end of a number where n = m * 2 and m equals the size of the longest string divided by two.
EDIT
Now that I have understood that b and d must be of the same length, it works almost everytime, but there are still exceptions: for example 1234*12
a = 123
b = 4
c = 1
d = 2
z0 = 123
z1 = 8
z2 = 127 * 3 - 123 - 8 = 250
z0_padded = 1230000
z2_padded = 25000
z0_padded + z1 + z2_padded = 1255008 != 14808
Here, assuming I split the strings correctly, the problem is the padding, but I do not get how I should pad. I read on Wikipedia that I should pad depending on the size of the biggest string (see a few lines up), there should be another solution.
The Karatsuba algorithm is a nice way to perform multiplications.
If you want it to work, b and d must be of the same length.
Here are two possibilities to compute 123x12 :
a= 1;b=23;c=0;d=12;
a=12;b= 3;c=1;d= 2;
Let's explain how it works for the second case :
123=12×10+3
12= 1×10+2
123×12=(12×10+3)×(1×10+2)
123×12=12×1×100+ (12×2+3×1)×10+3×2
123×12=12×1×100+((12+3)×(1+2)-12×1-3×2)×10+3×2
Let's explain how it works for the first case :
123=1×100+23
12=0×100+12
123×12=(1×100+23)×(0×100+12)
123×12=1×0×10000+ (1×12+23×0)×100+23×12
123×12=1×0×10000+((1+23)×(0+12)-1×0-23×12)×100+23×12
It also works with 10^k, 2^k or n instead of 10 or 100.

Day of Week function not working as intended in Atmega8

I have a C function that finds the Day of the week if given the complete date. This function works perfectly when I compile it on my laptop using gcc.
But when I compile the function for the Atmega8 using avr-gcc it gives the wrong answer. Could anyone help me figure out why?
Here's the C function
unsigned char *getDay(int year, int month, int day) {
static unsigned char *weekdayname[] = {"MON", "TUE",
"WED", "THU", "FRI", "SAT", "SUN"};
size_t JND = \
day \
+ ((153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5) \
+ (365 * (year + 4800 - ((14 - month) / 12))) \
+ ((year + 4800 - ((14 - month) / 12)) / 4) \
- ((year + 4800 - ((14 - month) / 12)) / 100) \
+ ((year + 4800 - ((14 - month) / 12)) / 400) \
- 32045;
return weekdayname[JND % 7];
}
For example, when I enter the date 01/01/2015 into the function on a laptop the function gives me the correct day of the week (Thursday) but on the atmega8 it gives me Monday.
Update:
The function sujithvm gave works! :D
But I still have no clue why the original function doesn't work on the avr. I tried uint32_t and int32_t. However, it looks like the day is always off by 3. Adding three to JND gives the correct day. That's a bit strange.
Try using this code
unsigned char *getDay(int y, int m, int d) {
static unsigned char *weekdayname[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
int weekday = (d += m < 3 ? y-- : y - 2 , 23 * m / 9 + d + 4 + y / 4 - y / 100 + y / 400) % 7;
return weekdayname[weekday];
}

Problems with my unix-epoch time converter

I wrote a simple function to fill three variables with the current year, month, and day.
However, for some reason it is not working correctly, and I can't seem to find the problem.
void getDate(int *year, int *month, int *date)
{
int epochTime,
monthLength,
functionYear,
functionMonth,
functionDate;
functionYear = 1970;
functionMonth = 1;
functionDate = 1;
epochTime = time(NULL);
while (epochTime > 1 * 365 * 24 * 60 * 60)
{
epochTime -= 1 * 365 * 24 * 60 * 60;
functionYear++;
}
monthLength = findMonthLength(functionYear, functionMonth, false);
while (epochTime > 1 * monthLength * 24 * 60 * 60)
{
printf("%d\n", epochTime);
epochTime -= 1 * monthLength * 24 * 60 * 60;
functionMonth++;
monthLength = findMonthLength(functionYear, functionMonth, false);
printf("functionMonth = %d\n", functionMonth);
}
while (epochTime > 1 * 24 * 60 * 60)
{
printf("%d\n", epochTime);
epochTime -= 1 * 24 * 60 * 60;
functionDate++;
printf("functionDate = %d\n", functionDate);
}
*year = functionYear;
*month = functionMonth;
*date = functionDate;
}
findMonthLength() returns an integer value which the length of the month it is sent. 1 = January, etc. It uses the year to test if it is a leap year.
It is currently April 3, 2013; however, my function finds April 15, and I can't seem to find where my problem is.
EDIT:
I got it. My first problem was that while I remembered to check for leap years when finding the months, I forgot about that when finding each year, which put me several days off.
My second problem was that I didn't convert to the local time zone from UTC
One problem could in this section:
while (epochTime > 1 * 365 * 24 * 60 * 60)
{
epochTime -= 1 * 365 * 24 * 60 * 60;
functionYear++;
}
Each iteration of this loop, a time in seconds corresponding to one normal year is subtracted. This does not account for leap years, where you need to subtract a time corresponding to 366 days.
For that section, you may want:
int yearLength = findYearLength(functionYear + 1);
while (epochTime > 1 * yearLength * 24 * 60 * 60)
{
epochTime -= 1 * yearLength * 24 * 60 * 60;
functionYear++;
yearLength = findYearLength(functionYear + 1);
}
with findYearLength(int year) being a function that returns the length in days of a given year.
One minor issue is that leap seconds are not accounted for. As only 35 of these have been added, that can be safely ignored in a calculation for a given day.
Why not use gmtime() or localtime() and be done with it? They return a structure with everything you need in it.
I made the complete solution based on yours, in Python. I hope it will help someone, someday. Cheers!
Use: getDate(unixtime)
def leapYear(year):
#returns True if the year is a leap year, return False if it isn't
if year % 400 == 0:
return True
elif year % 100 == 0:
return False
elif year % 4 == 0:
return True
else:
return False
def findMonthLength(year, month):
#returns an integer value with the length of the month it is sent.
#1 = January, etc. It uses the year to test if it is a leap year.
months1 = [0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
months2 = [0,31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if (leapYear(year)==True):
return months2[month]
else:
return months1[month]
def findYearLength(year):
#returns an integer value with the length of the year it is sent.
#It uses the year to test if it is a leap year.
if leapYear(year)==True:
return 366
else:
return 365
def getDate(epoch):
SECONDS_PER_YEAR = 0
SECONDS_PER_MONTH = 0
SECONDS_PER_DAY = 24 * 60 * 60
SECONDS_PER_HOUR = 60*60
SECONDS_PER_MIN = 60
epochTime = epoch
monthLength = 0
yearLength = 0
year = 1970
month = 1
day = 1
hour = 0
minu = 0
seg = 0
#Years
yearLength = findYearLength(year)
SECONDS_PER_YEAR = yearLength * SECONDS_PER_DAY
while (epochTime >= SECONDS_PER_YEAR):
epochTime -= SECONDS_PER_YEAR
year += 1
yearLength = findYearLength(year)
SECONDS_PER_YEAR = yearLength * SECONDS_PER_DAY
#Months
monthLength = findMonthLength(year, month)
SECONDS_PER_MONTH = monthLength * SECONDS_PER_DAY
while (epochTime >= SECONDS_PER_MONTH):
epochTime -= SECONDS_PER_MONTH;
month += 1
monthLength = findMonthLength(year, month)
SECONDS_PER_MONTH = monthLength * SECONDS_PER_DAY
#Days
while (epochTime >= SECONDS_PER_DAY):
epochTime -= SECONDS_PER_DAY;
day += 1
#Hours
while (epochTime >= SECONDS_PER_HOUR):
epochTime -= SECONDS_PER_HOUR;
hour += 1
#Minutes
while (epochTime >= SECONDS_PER_MIN):
epochTime -= SECONDS_PER_MIN;
minu += 1
#Seconds
seg = epochTime
print ("%d-%d-%d %d:%d:%d") % (year, month, day, hour, minu, seg)

Resources