Timespan Compare - c#

I have following time samples:
06:09
08:10
23:12
00:06 // next day
00:52
I have a sample 00:31 (nextday) that needs to be compared and check if its less then the above samples.
if (cdnTime > nextNode)
{
//dosomething
}
cdnTime here is the 00:31 and nextNode is the above given multiple samples. Time 00:31 is greater then all samples except 00:52 so I need the if statement to be false until it reaches 00:52. How do I achieve this. Keeping in mind the time samples switch to next day, do I need to make it as DateTime and then compare or is there any way of comparison with TimeSpan without dates.

Yes you need to somehow tell that it's another day. You can either use a DateTime, but you could also initialize a timespan with an additional day - it provides a Parse-method for this:
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
var cdnTime = TimeSpan.Parse("23:12", CultureInfo.InvariantCulture);
var nextTime = TimeSpan.Parse("01.00:03", CultureInfo.InvariantCulture);
Console.WriteLine(cdnTime.TotalMinutes);
Console.WriteLine(nextTime.TotalMinutes);
Console.WriteLine(cdnTime.CompareTo(nextTime));
Console.WriteLine(cdnTime < nextTime);
}
}
Another option would be to add the day afterwards:
var anotherTime = TimeSpan.FromMinutes(3);
anotherTime = anotherTime.Add(TimeSpan.FromDays(1));
Console.WriteLine(anotherTime.TotalMinutes);
You can try it out here:
https://dotnetfiddle.net/k39TIe

Related

Parsing Timex Expressions in .NET Core

Using LUIS engine, I receive XXXX-10-28 as a date in the Entity Value.
I've tried using Chronic to parse but Chronic does not work with timex library/formats.
I'm expecting following strings as inputs
XXXX-10-28 should equate to 2018-10-28 (future)
2018-10-02TMO should equate to 2018-10-02 i.e. tomorrow
Please note that XXXX-XX represents YYYY-MM but it doesn't have numeric values
Is there any library, or way to parse such strings to a valid datetime format in ASP.NET Core?
You can use the Microsoft.Recognizers.Text.DataTypes.TimexExpression package from NuGet. It's part of the Microsoft Recognizers Text project here on github
I found two ways you can use this library:
Parse the expression using a TimexProperty and guess the year yourself:
var parsed = new Microsoft.Recognizers.Text.DataTypes.TimexExpression.TimexProperty("XXXX-10-28");
Console.WriteLine(parsed.Year); // = null
Console.WriteLine(parsed.Month); // = 28
Console.WriteLine(parsed.DayOfMonth); // = 10
Resolve times useing the TimexResolver
var resolution = Microsoft.Recognizers.Text.DataTypes.TimexExpression.TimexResolver.Resolve(new [] { "XXXX-10-28" }, System.DateTime.Today)
The resolution.Values will contain an array with two resolution entries, one for the previous occurrence of that date and one for the next occurrence of that date (based on the DateTime you pass into the Resolve method.
Note that from personal experience and from what I saw on github, that at the time of writing, this package can be quite buggy with the more advanced expressions.
Use a custom format pattern:
using System;
using System.Globalization;
class MainClass {
public static void Main (string[] args) {
var format = "1234-10-30";
var date = DateTime.ParseExact(format, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Console.WriteLine (date.ToString("dd/MM/yyyy"));
}
}
Example
You can use DateTime.TryParse or DateTime.TryParseExact along with a custom date/time format string in order to accomplish this.
Based on your example, I think the format string you'd want is yyyy-MM-dd, although you may need to tweak this slightly.
Example:
var input = "2018-10-28";
var format = "yyyy-MM-dd";
DateTime parsed;
if (DateTime.TryParseExact(input, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed))
{
// Do whatever you want with "parsed"
}

How to change only the date portion of a DateTime, while keeping the time portion?

I use many DateTime in my code. I want to change those DateTimes to my specific date and keep
time.
1. "2012/02/02 06:00:00" => "2015/12/12 : 06:00:00"
2. "2013/02/02 12:00:00" => "2015/12/12 : 12:00:00"
I use this style to change, but it seem not the good way and I want to ask have any way to achieve this task.
DateTime newDateTime = new DateTime(2015,12,12,oldDateTime.Hour,oldDateTime.Minute,0);
A better way that preserves the seconds, milliseconds and smaller parts of the time would be:
DateTime newDateTime = new DateTime(2015,12,12) + oldDateTime.TimeOfDay;
Or you could make an extension method to apply a new Date to an existing DateTime and, at the same time, not trust the new date to be without a TimeOfDay on it:-
public static DateTime WithDate (this DateTime datetime, DateTime newDate)
{
return newDate.Date + datetime.TimeOfDay;
}
IMHO DateTime is one of the weakest parts of .NET. For example, a TimeSpan is not the same as a TimeOfDay nor can it represent a 'TimePeriod' (in months) - these are three separate concepts and mixing them up was a poor choice. Moving to DateTimeOffset is generally preferred or to the excellent Noda time library.
With the information you have given, I think this method is fine. If you want to avoid rewriting the oldDateTime.Hour,oldDateTime.Minute,0 piece often, you could create your own static class to simplify the method calls.
In your regular application:
class Program
{
static void Main(string[] args)
{
DateTime time = DateTime.Now;
DateTime newDateTime = MyDateTimeUtil.CreateDateFromTime(2015, 12, 12, time);
}
}
The static class that creates the DateTime value:
public static class MyDateTimeUtil
{
public static DateTime CreateDateFromTime(int year, int month, int day, DateTime time)
{
return new DateTime(year, month, day, time.Hour, time.Minute, 0);
}
}

Best way to get the current month number in C#

I am using C# to get current month number:
string k=DateTime.Now.Month.ToString();
For January it will return 1, but I need to get 01. If December is the current month, I need to get 12. Which is the best way to get this in C#?
string sMonth = DateTime.Now.ToString("MM");
Lots of different ways of doing this.
For keeping the semantics, I would use the Month property of the DateTime and format using one of the custom numeric format strings:
DateTime.Now.Month.ToString("00");
using System;
class Program
{
static void Main()
{
//
// Get the current month integer.
//
DateTime now = DateTime.Now;
//
// Write the month integer and then the three-letter month.
//
Console.WriteLine(now.Month);
Console.WriteLine(now.ToString("MMM"));
}
}
Output
5
May
DateTime.Now.Month.ToString("0#")

Regular DateTime question

I'm writing a service but I want to have config settings to make sure that the service does not run within a certain time window on one day of the week. eg Mondays between 17:00 and 19:00.
Is it possible to create a datetime that represents any monday so I can have one App config key for DontProcessStartTime and one for DontProcessEndTime with a values like "Monday 17:00" and "Monday 19:00"?
Otherwise I assume I'll have to have separate keys for the day and time for start and end of the time window.
Any thoughts?
thanks
You could use a utility that will parse your weekday text into a System.DayOfWeek enumeration, example here. You can then use the Enum in a comparison against the DateTime.Now.DayOfWeek
You can save the day of the week and start hour and endhour in your config file, and then use a function similar to the following:
public bool ShouldRun(DateTime dateToCheck)
{
//These should be read from your config file:
var day = DayOfWeek.Monday;
var start = 17;
var end = 19;
return !dateToCheck.DayOfWeek == day &&
!(dateToCheck.Hour >= start && dateToCheck.Hour < end);
}
You can use DayOfTheWeek property of the DateTime.
And to check proper time you can use DateTime.Today (returns date-time set to today with time set to 00:00:00) and add to it necessary amount of hours and minutes.
The DateTime object cannot handle a value that means all mondays. It would have to be a specific Monday. There is a DayOfWeek enumeration. Another object that may help you is a TimeSpan object. You could use the DayOfWeek combined with TimeSpan to tell you when to start, then use another TimeSpan to tell you how long
This is very rough code, but illustrates that you can check a DateTime object containing the current time as you wish to do:
protected bool IsOkToRunNow()
{
bool result = false;
DateTime currentTime = DateTime.Now;
if (currentTime.DayOfWeek != DayOfWeek.Monday && (currentTime.Hour <= 17 || currentTime.Hour >= 19))
{
result = true;
}
return result;
}

how should i create my own 'now' / DateTime.Now?

i'm starting to build a part of a system which will hold a lot of DateTime validations, and a lot of 'if it was done before now' or 'if it will start in an hour etc'.
Usual way to go is to use DateTime.Now to get the actual time.
I predict however, that during unit test that will give me a real headache because i will have to setup my testdata for the time when the test will run in stead of use a default set of test data.
So i thought: why not use my own 'now' so i can set the current datetime to any moment in time.
As i don't want to set the testservers internal clock i was thinking about this solution, and i was wondering what you think of it.
Base thought is that i use my own DateTime class.
That class gives you the current datetime, but you can also set your own time from outside.
public static class MyDateTime
{
private static TimeSpan _TimeDifference = TimeSpan.Zero;
public static DateTime Now
{
get
{
return DateTime.Now + _TimeDifference;
}
}
public static void SetNewNow(DateTime newNow)
{
_TimeDifference = newNow - DateTime.Now;
}
public static void AddToRealTime(TimeSpan timeSpan )
{
_TimeDifference = timeSpan;
}
public static void SubtractFromRealTime(TimeSpan timeSpan)
{
_TimeDifference = - timeSpan;
}
}
Some time ago i already read something about it. A short search for mock DateTime.Now with your favorite search engine should reveal enough links.
This seems to look quite interesting:
http://blog.typemock.com/2009/05/mockingfaking-datetimenow-in-unit-tests.html
what do u mean ?
if u need any specialization, so u can use Extension methods !
easily write an extension method for DateTime class and do whatever u need.

Categories