Julian Date Calculator - Changing values each run - c#

I got a simple Julian Date Calculator with the following code:
DateTime date = DateTime.UtcNow;
int month = date.Month > 2 ? date.Month : date.Month + 12;
int year = month > 2 ? date.Year : date.Year - 1;
int hour = date.Hour;
int minute = date.Minute;
int second = date.Second;
int millisecond = date.Millisecond;
double day = date.Day + hour / 24.0 + minute / 1440.0 + (second + millisecond * 1000) / 86400.0;
int isJulianCalendar = isJulianDate(year, month, date.Day) ? 0 : 2 - year + year / 100 / 4;
When I run the program, it returns a lower value than the previous one (e.g if I run now, it shows a value, but if I run in a couple of minutes, it shows another value).
From the .pdf I copied the expression, it says that the formula use UT time. Is there any relevant difference from the UTC time?

.NET has a built in JulianCalendar class, which you should probably use instead of writing your own code.

double day = date.Day + hour / 24.0 + minute / 1440.0 + (second + millisecond * 1000) / 86400.0;
The (second + millisecond * 1000) part seems intended to calculate fractional seconds, but to get that, you need to divide millisecond by 1000.0, not multiply it.
Note that as I pointed out in the comments, this only addresses the immediate problem you are asking about, it will likely not be sufficient to actually correctly calculate the Julian day. However, since you yourself have posted links to working answers showing a calculation of the Julian day without time, you should be able to get it working from here on.

Related

Adding two periods on nodatime

Where listObjAge is a list with multiple periods;
Period objTotalPeriod = listObjAge[0].period;
for (int i = 1; i < listObjAge.Count; i++) {
objTotalPeriod += listObjAge[i].period;
}
In-short:
What i am getting:
listObjAge[0].period + listObjAge[1].period = ????.
2 yr 1 mnth 28 days + 0 yr 8 mnth 30 days = 2 yr 9 mnth 58 days
// this result is not wrong but is there any way to correctly add days for the above code.
What i am expecting:
2 yr 1 mnth 28 days + 0 yr 8 mnth 30 days = 2 yr 10 mnth 28 days
As you can see i want to add results of two period. Is there any way we can achieve it using nodatime.
Solved:
I know its not correct theoretically. But it worked for me.
int intDays = 0;
for (int i = 0; i < listObjAge.Count; i++) {
intDays += listObjAge[i].period.Days; // adding all the days for every period
}
strYear = (intDays / 365).ToString();
strMonth = ((intDays % 365) / 30).ToString();
strDays = ((intDays % 365) % 30).ToString();
You should look at the user guide for Noda Time that describes arithmetic http://nodatime.org/2.0.x/userguide/arithmetic - look under the section "Adding a Period" for more information.
It's easiest to think about where this can be confusing with an example. Suppose we add "one month minus three days" to January 30th 2011:
Period period = Period.FromMonths(1) - Period.FromDays(3);
LocalDate date = new LocalDate(2011, 1, 30);
date = date + period;
If you give this puzzle to a real person, they may well come up with an answer of "February 27th" by waiting until the last moment to check the validity. Noda Time will give an answer of February 25th, as the above code is effectively evaluated as:
Period period = Period.FromMonths(1) - Period.FromDays(3);
LocalDate date = new LocalDate(2011, 1, 30);
date = date + Period.FromMonths(1); // February 28th (truncated)
date = date - Period.FromDays(3); // February 25th
The benefit of this approach is simplicity and predictability: when you know the rules, it's very easy to work out what Noda Time will do. The downside is that if you don't know the rules, it looks like it's broken.
With your code
According to the documentation, the result you are getting is the expected behavior based on the "rules". Simply, your addition operation on two two periods will evaluate to:
Years (2 + 0) = 2
Months(1 + 8) = 9
Days (28 + 30) = 58
Your comment:
this result is not wrong but is there any way to correctly add days for the above code.
What do you mean as "correct"? Are you saying that 28 + 30 = 58 is incorrect?
Alternatives
int days = 28 + 30; // carry over your days and +1 month or whatever logic you had in mind
int months = 1 + 8;
Period p1 = new PeriodBuilder { Days = days, Months = months }.Build();
It sounds like you're looking for something to normalize the months and days (and weeks?). The existing Normalize method deals with everything from "days downwards" (e.g. hours) so you can use that to start with:
public static Period NormalizeIncludingMonths(this Period period, int daysPerMonth)
{
period = period.Normalize();
int extraMonths = days / daysPerMonth;
int months = period.Months + extraMonths;
int extraYears = months / 12;
// Simplest way of changing just a few parts...
var builder = period.ToBuilder();
builder.Years += extraYears;
builder.Months = months % 12;
builder.Days = days % daysPerMonth;
return builder.Build();
}
So in your case, it sounds like you might want:
objTotalPeriod = objTotalPeriod.NormalizeIncludingMonths(31);
Note that arithmetic using this may well produce "odd" results, just as part of the nature of calendrical arithmetic.
Use this
public static Period add(Period b, Period c)
{
int years = b.year + c.year;
int months = b.month + c.month;
int days= b.days + c.days;
return new PeriodBuilder { Days = days, Months = months , Years = years}.Build();
}

I'm trying to find the difference between two times in two textboxes

textboxSart > textboxEnd
textboxEnd - textboxStart does the trick, but what if the start was 15:00 and the end was 2:00
I thought of this solution
24 - textboxStart + textboxEnd
I had to subtract 23:59 then add one minute because there is no 24 hours
textboxResult.text = (Convert.ToDateTime("23:59") - Convert.ToDateTime(textBoxStart.Text).AddMinutes(-1)).ToString();
But I can't add the value in textboxEnd
Convert.ToDateTime(textBoxStart.Text).AddMinutes(-1).AddHours(textboxEnd.tex)).ToString(); //i tried this, and i did convert to double but it didn't work
DateTime start = DateTime.Parse(textBoxStart.text);
DateTime end = DateTime.Parse(textBoxEnd.text);
To know difference in time unit minutes,
int hoursDifference = (int)end.Subtract(start).TotalMinutes;
TimeSpan var1 = TimeSpan.FromMinutes(Convert.ToDouble(textBox1.Text));
TimeSpan var2 = TimeSpan.FromMinutes(Convert.ToDouble(textBox2.Text));
double overtime = (var1.TotalMinutes * var2.TotalMinutes)/60;
textBox3.Text = overtime +" "+ "$" .ToString();

Converting Time to decimal

All i have to do that just find the overtime of employee. The attendance sheet comes in CSV file and I've already saved the data to a table. The data Field hours is 12:10:00.0000000, and The Working Hour per day is 11:00:00.0000000. I've calculated the difference between these two times using Timespan.
DateTime date, hours, working_hours ;
TimeSpan ot_hours = TimeSpan.Zero;
TimeSpan tot_hours = TimeSpan.Zero;
if (hours > working_hours)
{
ot_hours = (hours - working_hours);
}
This code has set in a loop. after completing the loop I need to stote the total overtime into another variable. so wrote
tot_hours += tot_hours + ot_hours;
And next I need to find the salary overtime amount for the employee.
I've tried to convert this tot_hours(TimeSpan ) into Decimal. But it didn't work.
tothrsvalue = Convert.ToDecimal(tot_hours);
totalvalue = rate * tothrsvalue;
Anyone here.. Please have a look and help me.. Thanks in advance.
the total calculation part is given below:
decimal basics = Convert.ToDecimal(dtamt.Rows[0]["Amount"].ToString());
decimal rate = 0;
rate = ((basics / 30) / 8);
txtrate.Text = rate.ToString("0.000");
tothrsvalue = Convert.ToDecimal(total);
totalvalue = rate * tothrsvalue;
txtamount.Text = totalvalue.ToString("0.000");
amt = Convert.ToDecimal(txtamount.Text);
Parsing TimeSpan to decimal does not too much sense because time is not a numeric value at all.
But you can use it's TotalHours property which returns double.
var total = tot_hours.TotalHours;
Y need to to convert a TimeSpan to a decimal ? Its cannot be done becuase it isn't numeric.
You probably want tot_hours.TotalHours, which is a double that includes the fractional portion.
or tot_hours.TotalHours.ToString("#.00");
ot_hours is now a Timestamps difference = Seconds ! Divide them by 60 to make minutes
example : total = 2 minutes = 120 seconds etc.)

hour interval based off of a 24 clock

I'm trying to figure an hour interval from a start time...
So if I allow the user to choose a value between 1 and 12 I want to figure out what times that represent in a 24 hour clock.
Lets say it is 9:00AM and they want to be notified every 4 hours during that day. I would need it to have the following values:
9AM
1PM
5PM
9PM
I'm trying to use the % (modulus) but I'm not getting what I'm expecting(4 % 24)... Any ideas?
Create a DateTime representing the current time (9:00 AM)
Create a TimeSpan representing the time interval (4 hours)
Use DateTime.Add(TimeSpan) method to produce the time of the next notification
The 12/24 hour clock does not play into it at all: you can format the next time the way you or your user wish - as a 24-hour clock using the "HH:mm" mask or as a 12-hour clock using "hh:mm" mask.
Here is a short code sample to get you started:
int hour = 9;
for (; hour <= 24; hour += 4)
Console.WriteLine("Hour = " + hour % 12);
Note the use of hour % 12.
Improvising... Use the % operator. As the % gets a value less than actual time (9:00AM) you know you need to change AM in PM... every time the result is less than actual time you have to change AM/PM or vice-versa.
int interval = 4;
int current = 9;
for(int i = current; i <= 24; i+=interval)
{
Console.WriteLine(i%12 + (i > 12 ? "PM" : "AM"));
}

How to Round to the Nearest 0.5?

in my application
Ex 1: Start time 12.30
(-)End time 16.00 here i get the value as 3.7 but i need to show this 3.7 as 3.5 in my application
Ex 2: Start time 12.00
(-)End time 16.00 here i get the value as 4.0 here there is no need to alter the value
(1.7,2.7,3.7,4.7,.... etc ) as to be represented as(1.5,2.5,3.5,4.5,.. etc )
so how to write an function for this where if the vale contains(1.7,2.7) i should change to 1.5,2.5
or if it contains 1.0,2.0 then there is no need to replace any value?
This extension method ought to do the job:
public decimal RoundToNearestHalf(this decimal value)
{
return Math.Round(value * 2) / 2;
}
var num1 = (3.7).RoundToNearestHalf(); // 3.5
var num1 = (4.0).RoundToNearestHalf(); // 4.0
I've used the decimal type in the code because it seems you want to maintain base 10 precision. If you don't, then float/double would do just as well, of course.
Use the DateTime type. Subtracting DateTime types returns a TimeSpan. Use TimeSpan.TotalHours to get your result. E.g.:-
var x = DateTime.Parse("12:30");
var y = DateTime.Parse("16:00");
Console.WriteLine((y - x).TotalHours);
Use DateTime type to work with time. Example:
string time1 = "12:30";
string time2 = "16:00";
TimeSpan diff = DateTime.Parse(time2)-DateTime.Parse(time2);
string diffString = diff.ToString("hh:mm"); // will be 03:30
Multiply hours with 60 and add minutes. You'll get total number of minutes.
12hours and 30 minutes = 720 + 30 = 750 minutes.
16 hours = 960 minutes.
Subtract the first value from the other and divide it by 60
(960 - 750) / 60 = 210 / 60 = 3.5
You should use TimeSpan and round it off:
TimeSpan startTime = new TimeSpan(12, 30, 0);
TimeSpan endTime = new TimeSpan(16, 0, 0);
TimeSpan span = endTime - startTime;
double totalHours = span.TotalHours;
double roundedToHalf = Math.Round(totalHours * 2) / 2;
Console.WriteLine(roundedToHalf);
UPDATE:
If the start and end time are from different dates, you should use DateTime for startTime and endTime.
If the values in your question represent times you can't do decimal arithmetic with them and expect time values as results.
You need to manipulate the values as times
I don't know C#, but it must have some time functions.
Have the times as DateTime then use Timspan to find the difference between the two times?
Times are not integers or floats. You can't work with them as if they are - you wouldn't try to do integer math using the String class, would you?
DateTime and TimeSpan are you friends for this kind of data manipulation.
You can use the C# Floor and Ceil method of the Math Class. Read more about it in the below URLs:
http://msdn.microsoft.com/en-us/library/system.math.ceiling(VS.71).aspx
http://dotnetperls.com/math-floor
string i = "2.0";
if (i == "2.3" || i == "3.3" || i == "4.3")
{
string strReplace = i.Replace(".3", ".5");
}
else
{
string strReplace = i;
}

Categories

Resources