I try to calculate the ramadan feast. I use the HijriCalendar for this issue.
I have check wikipedia and ramadan feast is on the end of the islamic month Ramadan.
Some dates are good but other on the wrong day (1 day deferred)
var hijriCalendar = new HijriCalendar();
for (var i = 1431; i <= 1438; i++)
{
var dateTime = new DateTime(i, 10, 1, hijriCalendar);
Console.WriteLine(dateTime.ToString("yyyy-MM-dd"));
}
Public Holiday Ramadan Feast
First value calculated, second the correct value
2010-09-09 (2010-09-09)
2011-08-30 (2011-08-30)
2012-08-18 (2012-08-19) WRONG +1
2013-08-07 (2013-08-08) WRONG +1
2014-07-28 (2014-07-28)
2015-07-17 (2015-07-17)
2016-07-06 (2016-07-05) WRONG -1
2017-06-25 (2017-07-25)
Source of correct date
https://www.timeanddate.com/holidays/turkey/ramadan-feast
It looks like the C# HijriCalendar acknowledges that the dates of Ramadan can be off and offers a HijriCalendar.HijriAdjustment Property to account for variances from year to year.
This implementation of the HijriCalendar class adjusts the calendar
date by adding or subtracting a value from zero to two days to
accommodate the variances in the start and the end of Ramadan and to
accommodate the date difference between countries/regions
Check out this page for more information about it.
https://msdn.microsoft.com/en-us/library/system.globalization.hijricalendar.hijriadjustment(v=vs.110).aspx
Related
I can get week number if I use normal way like that. As you know this one calculates week number according to normal start date which is 01.01.2015.
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(mydate, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
But I want to change that start date. For instance my first week of year will be 01.07.2015 and according to that date I want to calculate week of year for given date.
Substract a difference between new year and your start date from the mydate object
var startDate = new DateTime(2015, 7, 1);
var newYear = new DateTime(2015, 1, 1);
var culture = CultureInfo.CurrentCulture;
var weekOfYear = culture.Calendar.GetWeekOfYear(
mydate.Add(newYear - startDate),
culture.DateTimeFormat.CalendarWeekRule,
culture.DateTimeFormat.FirstDayOfWeek);
Maybe you could calculate the week number for your start date (e.g 01.07.2015 - 27) and then what is the week number for the actual date - e.g 12.12.2015 (50), and then just subtract - in this case 23?
Just subtract the number of days between your wished week-1 date and the default start date and use that offset each time you calculate (.AddDays(offset)).
That way :
DateTime startDateTime = new DateTime(2015,07,01) ;
int fisrtDayOfWeek = 0 ; // 0:sunday for US, 1:Monday for many other coutries
DateTime week1StartDateTime = startDateTime ;
for (int i=1;i<6;i++) if ((int)startDateTime.AddDays(i).Day==fisrtDayOfWeek )
week1StartDateTime = startDateTime.AddDays(i) ;
int weekNumber= mydate<week1StartDateTime ? 1 :
((int)(mydate-week1StartDateTime).TotalDays)/7+1 ;
// note : casting double to int provides the floor (not round)
I need to calculate the annual use of a service starting from the date of signing. Something like:
select Count(*) from TABLENAME where Date >= MYDATE
MYDATE need to be calculate from a subscription date and I need to get the last year date from subscription referring to the current date
Some examples:
subscription date: 2007-06-29
if current date is : 2015-04-29 then date is: 2014-06-29
if current date is : 2015-06-29 then date is: 2015-06-29
if current date is : 2015-06-29 then date is: 2015-06-29
I'm using c# to calculate the date but it crashes in leapyear:
var date = new DateTime(DateTime.Now.Year, subscriptionDate.Month, subscriptionDate.Day);
if (DateTime.Now.Date < date)
{
date = date.AddYears(-1);
}
I was wondering if there were a clever/better way to do it in c# or mysql also handling leapyear
---UPDATE----
Running example with suggested solutions
Well, I'd do it in Noda Time, myself:
LocalDate subscriptionDate = ...;
LocalDate today = ...; // Need to take time zone into account
int years = Period.Between(subscriptionDate, today);
return subscription.PlusYears(years);
With .NET that would be slightly harder, but I'd still go for the approach of adding years (and letting it do the truncation for Feb 29th):
// Only call this *once* - otherwise you could get inconsistent results
DateTime today = DateTime.Today;
int years = today.Year - subscriptionDate.Year;
DateTime candidate = subscriptionDate.AddYears(years);
// We might have overshot, in which case lower the number of years.
return candidate <= today ? candidate : subscriptionDate.AddYears(years - 1);
Thanks to Yuri Dorokhov answer and Jon Skeet suggestion
I found a solution that works well and handle leap year:
int year = DateTime.Now.DayOfYear >= subscriptionDate.DayOfYear ?
DateTime.Now.Year : DateTime.Now.Year - 1;
var date = new DateTime(year, 1, 1).AddDays(subscriptionDate.DayOfYear - 1);
--------UPDATE------
I leave here this answer as reference but it does not handle well leap year so don't use it
Use mysql DATE_SUB function
DATE_SUB(Date, INTERVAL 1 YEAR)
This question already has answers here:
how to calculate number of weeks given 2 dates?
(7 answers)
Closed 9 years ago.
Lets say, I have two date Order date - 1/1/2014 and Delivery date - 6/2/2014. Now if I want to calculate how much work week its taken (Order date-delivery date), how can I do it in c#.
If you want the number of worked days in a date range, you can use this:
var from = DateTime.Today.AddDays(-10);
var to = DateTime.Today;
var daysOfWeek = new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Tuesday
, DayOfWeek.Wednesday, DayOfWeek.Friday
, DayOfWeek.Thursday };
var days = Enumerable.Range(0, 1 + to.Subtract(from).Days)
.Select((n, i) => from.AddDays(i).DayOfWeek)
.Where(n => daysOfWeek.Contains(n.DayOfWeek));
If you want the number of weeks during a date range, use this:
(int)((to - from).TotalDays/7)
(int)((DeliveryDate-OrderDate).TotalDays/7)
I am presuming by "how much workweek" you mean "how many workdays". This is not so straightforward as it depends on the culture and you need to take holidays into account.
If you rely on Mon through Fri being the work days you could use a solution similar to what was discussed in c# DateTime to Add/Subtract Working Days, counting each day from Order Date to Delivery Date for which the conditions hold.
That Q&A still leaves you with the issue of how to determine the holidays of a certain region (be warned - in Switzerland each part of the country has different holidays!).
Update: From Nagaraj's suggested link I gather that you might also refer to "weeks" as chunks (that is "how many workweeks it has taken"). If so, in turn, you will need to define how many days of a week must be taken to take the week into account...
I'm using strings and convert that to dates, because I'm not sure where you get your dates and in what form. Adjust your code accordingly.
string orderDate = #"1/1/2014";
string deliveryDate = #"6/2/2014";
// This will give you a total number of days that passed between the two dates.
double daysPassed = Convert.ToDateTime(deliveryDate).
Subtract(Convert.ToDateTime(orderDate)).TotalDays;
// Use this if you want actual weeks. This will give you a double approximate. Change to it to an integer round it off (truncate it).
double weeksPassed = daysPassed / 7;
// Use this if you want to get an approximate number of work days in those weeks (based on 5 days a week schedule).
double workDaysPassed = weeksPassed * 5;
I guess you are not interested in working days but weeks. You can use GetWeekOfYear:
http://msdn.microsoft.com/en-us/library/system.globalization.calendar.getweekofyear%28v=vs.110%29.aspx
EDIT
To respond to the comment, here some code example:
int start = System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(new DateTime(2014, 1, 14), System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
int end = System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(new DateTime(2014, 2, 3), System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
int weeks = end - start;
That should give you the weeks needed.
I have an int representing a number of Gregorian days from Year Zero (thanks, Erlang). How do I convert this to a DateTime object? I can't create a DateTime(0,0,0), and Convert.DateTime(int) throws an invalid cast.
If you have a number, and you know the date that it represents (from Erlang), you can calculate the offset from any date you choose. Preferred is a base date in the zone that the results will be in, this will minimize calender conversion effects. (The Gregorian calendar is valid from about 1600).
If you know that offset, you can use the choosen date as the base for future calculations.
Example:
I want my offset date to be: 1/1/2000. This will be the date that I calculcate from.
I know number 37892 from erlang is actually 1/1/1970 (this is an example).
Then I can calculate the offset:
var myBaseDate = new DateTime(2000,1,1);
var exampleNrOfDays = 37892;
var exampleDate = new DateTime(1970,1,1);
var offset = exampleDate - myBaseDate;
var offsetInDays = exampleNrOfDays - (int)offset.TotalDays;
// Now I can calculate
var daysFromErlang = 30000; // <= example
var theDate = myBaseDate.AddDays(daysFromErlang - offsetInDays);
This shows how to calculate number of days from a given date. http://dotnetperls.com/datetime-elapsed
if day zero is 0/0/0 then it is 365+30+1 day before DateTime.Min which is 1/1/1. So you can subtract days from year zero by 365+30+1 and add to DateTime.Min
Now Month 1 is January which is 31 days but what is Month 0? I assumed it is 30 days.
With 0, you probably mean 0:00 on the 1st of January, year 1. There is no year 0 in the gregorian calendar as far as i know.
If the above is right, you can just do
DateTime date = new DateTime();
date.AddDays(numberOfDays);
because the default constructor 'DateTime()' returns the "zero" DateTime object.
See the DateTime reference for more informations.
I am not sure if you are aware of this, but there is a Calendar object in System.Globalization. Not only that but there is a GregorianCalendar object as well.
so try this:
GregorianCalendar calendar = new GregorianCalendar();
DateTime minSupportedDateTime = calendar.MinSupportedDateTime;
//which is the first moment of January 1, 0001 C.E.
DateTime myDate = minSupportedDateTime.AddDays(55000);
//this is when you add the number of days you have.
Thanks,
Bleepzter
PS. Don't forget to mark my answer if it has helped you solve your problem! Thanks.
So I have an application that needs to get a date focus so it can run appropriately. Given a particular date to focus on it needs to know what week it is in. I'm calculating weeks based on Monday dates. And I'm wondering if my focus on Mondays is excessive.
public static DateTime PreviousMonday(this DateTime dt)
{
var dateDayOfWeek = (int)dt.DayOfWeek;
if (dateDayOfWeek==0)
{
dateDayOfWeek = dateDayOfWeek + 7;
}
var alterNumber = dateDayOfWeek - ((dateDayOfWeek*2)-1);
return dt.AddDays(alterNumber);
}
/// <summary>
/// Personal tax week starts on the first Monday after the week with 6th April in unless 6th April is a Monday in
/// which case that starts the first week. In a leap year this means you can have a week 53 which due to the mod 4 approach of calculating
/// flexi week means you get a 5 week flexi period.
/// As such this method forces the weeks into the range 1 - 52 by finding the week number for the week containing 6th April and
/// the number for the current week. Treating the 6th April week as week 1 and using the difference to calculate the tax week.
/// </summary>
public static int GetTaxWeek(this DateTime dt)
{
var startTaxYear = GetActualWeekNumber(new DateTime(DateTime.Now.Year, 4, 6));
var thisWeekNumber = GetActualWeekNumber(dt);
var difference = thisWeekNumber - startTaxYear;
return difference < 0 ? 53 + difference : difference + 1;
}
private static int GetActualWeekNumber(DateTime dt)
{
var ci = System.Threading.Thread.CurrentThread.CurrentCulture;
var cal = ci.Calendar;
var calWeekRule = ci.DateTimeFormat.CalendarWeekRule;
var fDoW = ci.DateTimeFormat.FirstDayOfWeek;
return cal.GetWeekOfYear(dt, calWeekRule, fDoW);
}
public static int PeriodWeek(this DateTime dt)
{
var rawPeriodWeek = GetTaxWeek(dt) % 4;
return rawPeriodWeek == 3 ? 1 : rawPeriodWeek + 2;
}
}
The system runs a rolling 4 week schedule starting in the first tax week and needs to behave differently depending on where in the schedule it is. So you can see...
Get a date from a user (say userDate)
Call userDate=userDate.PreviousMonday();
to get to the Monday of the week
given - where Sunday is the week end
Call userDate.PeriodWeek(); and get
the Period you are in from 1 to 4.
GetTaxWeek is public because it is used elsewhere... I also replace the date as it is used more than once and I don't want to have to remember to change it more than once.
Can I see the wood for the trees? Or is there a more error free way of doing this.
I think you can greatly simplify your code using the GregorianCalendar inside System.Globalization. Here you can get the week number for a given date like this:
GregorianCalendar gc = new GregorianCalendar();
int weekno = gc.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
You see here that you can give the rules for how to caclulate the week number according to your local rules. Like here in Norway, we have Monday as our first week day, and the first week of the year is the first week that has four or more days. Set this to your culture specific rules to get the correct week numbers.
Some of your specific handling you still ahve to do by hand, but some of the clutter can be removed using this at least :)
why are you not using a DateTimePicker control? it will tell you the day for the user selected date. Then you can simply subtract no. of days from it to get date for monday. For example:
I'm using a DateTimePicker control and named it dtpTemp. the event used is
dtpTemp_ValueChanged()
dtpTemp.Value.DayOfWeek - will give you the day: tuesday, wednesday, thursday etc.
then you can use following code with switch case accordingly:
dtpTemp.Value.AddDays(num); to get date for monday
here num will have -ve values which will depend on day calculated above. Values: -1 for tuesday, -2 for wednesday, -3 for thursday and so on.
plus, using a datetimepicker will also have a positive impact on the UI itself.