I have two times like
Time A:09:00 AM
and Time B:06:00 PM
I want to get the total hours between Time A and Time B
and show it with the time span of 1 hour
e.g:
09:00 AM
10:00 AM
11:00 AM
12:00 PM
upto
06:00 PM
I think you need something like;
DateTime dt1 = DateTime.Parse("09:00 AM");
DateTime dt2 = DateTime.Parse("06:00 PM");
while (dt1 <= dt2)
{
Console.WriteLine(dt1.ToString("hh:mm tt"));
dt1 = dt1.AddHours(1);
}
Output will be;
09:00 AM
10:00 AM
11:00 AM
12:00 PM
01:00 PM
02:00 PM
03:00 PM
04:00 PM
05:00 PM
06:00 PM
Here's a demonstration.
I'm sorry but I don't understand why you interested in TimeSpan on this case. It is a duration in time. You need to get every hour times with DateTime.
Use this function:
public static IEnumerable<DateTime> GetHours(DateTime startTime, DateTime endTime)
{
var currentTime = startTime;
while (currentTime <= endTime)
{
yield return currentTime;
currentTime = currentTime.AddHours(1);
}
}
If you just need the number of hours between two events, you can use a variation of
(endTime - startTime).TotalHours
This will return a double. To calculate the number of items returned from the iterator, use
(int)(endTime - startTime).TotalHours + 1
Related
Here's my code
DateTime TimeIn = "8:00 AM",
TimeOut="2:00 AM";
double Total;
private void compute()
{
Total = (TimeOut - TimeIn).TotalHours;
}
8:00am to 2:00am should result 18 hours.But mine is resulting -7
Another problem is when i typed 24:00 as time out C# couldn't recognize it as Time.
It works properly when the TimeOout is less than 12:00am. like 11:59pm backwards.
(eg.: 11:30PM - 8:00AM) it computes properly.
Please Help.
Add +24 hours when negative result.
may be this could help you:
string TimeIn= "8:00 AM";
string TimeOut= "2:00 AM";
TimeSpan duration = DateTime.Parse(TimeOut).Subtract(DateTime.Parse(TimeIn));
The way you have declared the datetime Value is wrong. The right way to do it is by converting the string to datetime format
DateTime TimeIn = Convert.ToDateTime("08:00");
DateTime TimeOut = Convert.ToDateTime("02:00");
TimeSpan ts = TimeIn - TimeOut;
If you need the 18 hours span that you're looking for you'll have to pass the date value as well while assigning data to the variables
i have in c# this list of the Rendez-vous:
ID Date_Start Date_End
18/11/2016 08:00 18/11/2016 14:00
18/11/2016 09:00 18/11/2016 11:30
18/11/2016 14:00 18/11/2016 16:30
18/11/2016 17:30 18/11/2016 19:00
How I can check the part of time is busy or no ?
for exemple how to check the part time from 18/11/2016 11:30 to 18/11/2016 14:00 is busy ?
thanks for your Response.
It's hard to tell exactly what you're looking for from your question. My interpretation is that you want to know whether a given range of dates overlaps with any range in your list. Here's the code to do that:
Rendezvous[] rendezvous = ... // you already have this
DateTime startTime = ... // e. g. 18/11/2016 11:30
DateTime endTime = ... // e. g. 18/11/2016 14:00
var isBusy = rendezvous.Any(r => !(endTime < r.Date_Start || startTime > r.Date_End));
I am building something like exam datesheet. I'm currently having issues in finding conflicts between time..
I have a List of strings that stores time intervals like-
List<string> times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Now suppose, if want to add below time to the list, I first want to check it does not conflict with the time that is already there.
So, in below case, it should not be added.
if(NotConflict("5:00 PM to 7:00 PM"))
times.Add("5:00 PM to 7:00 PM");
But the following can be added since there is no conflict.
if(NotConflict("2:00 PM to 5:00 PM"))
times.Add("2:00 PM to 5:00 PM");
I cannot use DateTime here because it the very old system and time is being stored like above. And it being used at many places.
This should work:
private static Tuple<DateTime, DateTime> ParseDate(string dateTimes)
{
var split = dateTimes.Split(new[] { " to " }, StringSplitOptions.None);
var time1 = DateTime.ParseExact(split[0], "h:mm tt",
CultureInfo.InvariantCulture);
var time2 = DateTime.ParseExact(split[1], "h:mm tt",
CultureInfo.InvariantCulture);
return Tuple.Create(time1, time2);
}
private static bool NotConflict(IEnumerable<string> times, string time) {
var incTime = ParseDate(time);
return !times.Any(t => {
var parsed = ParseDate(t);
return incTime.Item1 <= parsed.Item2 && parsed.Item1 <= incTime.Item2;
});
}
public static void Main()
{
var times = new List<string>();
times.Add("6:00 PM to 9:00 PM");
times.Add("10:00 AM to 1:00 PM");
Console.WriteLine("No Conflict 5:00 PM to 7:00 PM: {0}", NotConflict(times, "5:00 PM to 7:00 PM"));
Console.WriteLine("No Conflict 2:00 PM to 5:00 PM: {0}", NotConflict(times, "2:00 PM to 5:00 PM"));
}
ParseDate will return a formatted tuple with the start and end time in Item1 and Item2 respectively. Then you simply use Linq's Any function to filter and make sure that you don't return any that fall within the bounds.
See the DotNet fiddle here.
I have a time range 11:00 PM to 5:00 AM. (night hours range)
I have date range for eg.,
2014-04-01 00:00:00 to 2014-04-02 23:59:59
Now I need to calculate how many night hours are present in the given date range.
For the above example it should return 11 hours 59 minutes 59 seconds
Explanation:
2014-04-01 00:00 AM to 2014-04-01 5:00 AM = 5 hours
2014-04-01 11:00 PM to 2014-04-02 5:00 AM = 6 hours
2014-04-02 11:00 PM to 2014-04-02 11:59:59 PM = 0 hour 59 minutes 59 seconds
one second approximation is okay.
If these are strings, you need to parse them to DateTime with DateTime.ParseExact method and then get difference them with - operator. This gets you a TimeSpan. I see your strings have different formats. You need to parse them matched format one by one.
After that, you can use TimeSpan properties like;
string s = "2014-04-01 00:00 AM";
var date = DateTime.ParseExact(s,
"yyyy-MM-dd HH:mm tt",
CultureInfo.InvariantCulture);
string s1 = "2014-04-01 5:00 AM";
var date1 = DateTime.ParseExact(s1,
"yyyy-MM-dd H:mm tt",
CultureInfo.InvariantCulture);
TimeSpan ts = date1 - date;
Console.WriteLine(string.Format(#"{0} hours {1} minutes {2} seconds",
ts.Hours, ts.Minutes, ts.Seconds));
Output will be;
5 hours 0 minutes 0 seconds
If they are already DateTime, just use - operator and use .Hours, .Minutes and .Seconds properties of TimeSpan structure.
There is a project called Calculating Business Hours which is calculate business hours between two DateTime. You can implement your own night shift hours based this project.
You can use the CalendarPeriodCollector of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public void NightHours()
{
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.CollectingHours.Add( new HourRange( 0, 5 ) ); // working hours
filter.CollectingHours.Add( new HourRange( 23, 24 ) ); // working hours
CalendarTimeRange testPeriod =
new CalendarTimeRange( new DateTime( 2014, 4, 1 ),
new DateTime( 2014, 4, 3 ) );
Console.WriteLine( "Calendar period collector of period: " + testPeriod );
CalendarPeriodCollector collector =
new CalendarPeriodCollector( filter, testPeriod );
collector.CollectHours();
Console.WriteLine( "Duration: " + new DateDiff( collector.Periods.TotalDuration ) );
} // NightHours
For example, a recurring event occurs every Saturday at 08:00 Central European Time (or 08:00 CEST during summers), regardless of whether there is DST or not. How do I come up with a list of DateTimes representing this event?
Are you looking for this?
List<DateTime> Schedule = new List<DateTime>();
DateTime Base = new DateTime(2013, 11, 9, 8, 0, 0);
for (int i = 0; i < 365; i++)
Schedule.Add(Base.AddDays(i));
Here's a way to get a list of DateTimeOffset values that accurately represent what you asked. If you like, you can convert to DateTime with either result.DateTime or result.UtcDateTime depending on what you are looking for. This will return the next N days from today, in the time zone provided, accounting for DST.
public static IEnumerable<DateTimeOffset> GetNextDaysInZone(int count, DayOfWeek dayOfWeek, TimeSpan localTimeOfDay, string timeZoneId)
{
// get today in the time zone specified
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
DateTime today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz).Date;
// figure out how many days we are away from the target day of week
int adjustment = dayOfWeek - today.DayOfWeek + (dayOfWeek < today.DayOfWeek ? 7 : 0);
// calculate and return the results
return Enumerable.Range(0, count)
.Select(x =>
{
DateTime dt = today.AddDays(x * 7 + adjustment).Add(localTimeOfDay);
TimeSpan offset = tz.GetUtcOffset(dt);
return new DateTimeOffset(dt, offset);
});
}
Example usage:
DayOfWeek dayOfWeek = DayOfWeek.Saturday;
TimeSpan localTimeOfDay = new TimeSpan(8, 0, 0);
// Note: Despite the name, this represents Central European Time, including both CET and CEST.
string tzid = "Central Europe Standard Time";
var results = GetNextDaysInZone(5, dayOfWeek, localTimeOfDay, tzid);
foreach (var result in results)
{
Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss zzz} ({1:yyyy-MM-dd HH:mm:ss} UTC)", result, result.UtcDateTime);
}
Results:
2013-11-16 08:00:00 +01:00 (2013-11-16 07:00:00 UTC)
2013-11-23 08:00:00 +01:00 (2013-11-23 07:00:00 UTC)
2013-11-30 08:00:00 +01:00 (2013-11-30 07:00:00 UTC)
2013-12-07 08:00:00 +01:00 (2013-12-07 07:00:00 UTC)
2013-12-14 08:00:00 +01:00 (2013-12-14 07:00:00 UTC)
And for good measure, if you'd like to ditch the built-in date/time api and go with something much more robust and reliable, I suggest you try Noda Time. Here is how you might do the same thing as above using Noda Time.
public static IEnumerable<ZonedDateTime> GetNextDaysInZone(int count, IsoDayOfWeek dayOfWeek, LocalTime localTimeOfDay, string timeZoneId)
{
// get today in the time zone specified
DateTimeZone tz = DateTimeZoneProviders.Tzdb[timeZoneId];
Instant now = SystemClock.Instance.Now;
LocalDate today = now.InZone(tz).Date;
// figure out how many days we are away from the target day of week
int adjustment = dayOfWeek - today.IsoDayOfWeek + (dayOfWeek < today.IsoDayOfWeek ? 7 : 0);
// calculate and return the results
return Enumerable.Range(0, count)
.Select(x => (today.PlusDays(x * 7 + adjustment) + localTimeOfDay).InZoneLeniently(tz));
}
Example Usage:
IsoDayOfWeek dayOfWeek = IsoDayOfWeek.Saturday;
LocalTime localTimeOfDay = new LocalTime(8, 0, 0);
// This is just one of the zones that follows CET/CEST
string tzid = "Europe/Berlin";
var results = GetNextDaysInZone(5, dayOfWeek, localTimeOfDay, tzid);
LocalDateTimePattern localPattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
OffsetPattern offsetPattern = OffsetPattern.CreateWithInvariantCulture("m");
foreach (var result in results)
{
Console.WriteLine("{0} {1} ({2} UTC)",
localPattern.Format(result.LocalDateTime),
offsetPattern.Format(result.Offset),
localPattern.Format(result.WithZone(DateTimeZone.Utc).LocalDateTime));
}
Results:
2013-11-16 08:00:00 +01:00 (2013-11-16 07:00:00 UTC)
2013-11-23 08:00:00 +01:00 (2013-11-23 07:00:00 UTC)
2013-11-30 08:00:00 +01:00 (2013-11-30 07:00:00 UTC)
2013-12-07 08:00:00 +01:00 (2013-12-07 07:00:00 UTC)
2013-12-14 08:00:00 +01:00 (2013-12-14 07:00:00 UTC)
Both of these approaches take the path of assuming a lenient conversion for times that either don't exist or exist twice on the days of daylight saving time transitions. If you'd like it to not be lenient, then you have some more work to do. But I think that's beyond the scope of what you asked for.