Showing posts with label DateTime. Show all posts
Showing posts with label DateTime. Show all posts

February 24, 2021

DateTime String Format Extensions

Bear in mind that a DateTime should generally be stored in Universal format and converted to local format when be displayed in a GUI or used in a report. This handy extension for date time format strings saves having to remember their obscure format codes or look them up every time.

// See here for more info 
// https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
public static class DateTimeToStringExtender
{
    public static bool ParseGeneralShortDateTime(this string dateTimeStr, out DateTime dateTime)
    {
        var format = "g"; // Standard short date time format: "dd/MM/yyyy HH:mm:ss" for UK
        bool result = false;
        CultureInfo provider = CultureInfo.CurrentCulture;
        result = DateTime.TryParseExact(dateTimeStr.Trim(), format, provider, DateTimeStyles.None, out dateTime);
        return result;
    }

    /// <summary>
    /// Convert a DateTime to a YearMonthDay string of the form yyyy/MM/dd
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>YearMonthDay string of the form yyyyMMdd</returns>
    public static string ToYyyyMmDdString(this DateTime dt, char separator = char.MinValue)
    {
        string format = "yyyyMMdd";
        if (!char.IsControl(separator))
        {
            format = "yyyy" + separator + "MM" + separator + "dd";
        }
        var res = dt.ToString(format);
        return res;
    }

    /// <summary>
    /// Convert a DateTime to a YearMonthDay string of the form DdMmYyyy
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>YearMonthDay string of the form DdMmYyyy</returns>
    public static string ToDdMmYyyyString(this DateTime dt, char separator = char.MinValue)
    {
        string format = "ddMMyyyy";
        if (!char.IsControl(separator))
        {
            format = "dd" + separator + "MM" + separator + "yyyy";
        }
        return dt.ToString(format);
    }


    /// <summary>
    /// Convert a DateTime to a YearMonthDay string of the form yyyyMMdd_HHmmss where the hour is in the 24 hour format
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>YearMonthDay string of the form yyyyMMdd_HHmmss</returns>
    public static string ToYyyyMmDd_HhMmSsString(this DateTime dt)
    {
        return dt.ToString("yyyyMMdd_HHmmss");
    }

    /// <summary>
    /// Convert a DateTime to a YearMonthDay string of the form yyyyMMdd_HHmmss_ffffff where the hour is in the 24 hour format
    /// Useful for creating randomised filenames based upon the date
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>YearMonthDay string of the form yyyyMMdd_HHmmss_ffffff</returns>
    public static string To_YyyyMmDd_HhMmSs_ffffff(this DateTime dt)
    {
        return dt.ToString("yyyyMMdd_HHmmss_ffffff");
    }

    /// <summary>
    /// Convert a DateTime to a YearMonthDay string of the form yyyyMMdd_HHmmss where the hour is in the 24 hour format
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>YearMonthDay string of the form yyyyMMdd_HHmmss</returns>
    public static string ToYyyyMmDd_HhMmSsString(this DateTime dt, char dateSeparator = char.MinValue, char timeSeparator = char.MinValue)
    {
        string format = "yyyyMMdd_HHmmss";
        if (!char.IsLetterOrDigit(dateSeparator) && !char.IsControl(dateSeparator))
        {
            format = "yyyy" + dateSeparator + "MM" + dateSeparator + "dd" + "_" + "HH" + timeSeparator + "mm" + timeSeparator + "ss";
        }
        return dt.ToString(format);
    }


    /// <summary>
    /// Emits a date time (culture independent) string of the form 
    /// "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"
    /// (eg.: "Sun, 09 Mar 2008 16:05:07 GMT"). 
    /// Works on universal date times only
    /// </summary>
    /// <param name="dateTime">target date time to convert to a string</param>
    /// <returns>dateTime formatted as a string</returns>
    public static string ToRfc1123FormatString(this DateTime dateTime)
    {
        string result = dateTime.ToUniversalTime().ToString("r");
        return result;
    }

    /// <summary>
    /// Convert a DateTime to a string of the form "2008-03-09 16:05:07Z"
    /// where the '-' character is culture dependant
    /// </summary>
    /// <param name="dt">target</param>
    /// <returns>string of the form "2008-03-09 16:05:07Z" where '-' character is culture dependant</returns>
    public static string ToUniversalSorta­bleString(this DateTime dt)
    {
        return dt.ToUniversalTime().ToString("u");
    }

    // 2009-06-15T13:45:30 --> Monday, June 15, 2009 8:45:30 PM (for en-US)
    public static string ToUniversalFull(this DateTime dateTime)
    {
        var res = dateTime.ToUniversalTime().ToString("U");
        return res;
    }

    /// <summary>
    /// Emits a sortable date time (culture independent) string of the form "yyyy'-'MM'-'dd'T'HH':'mm':'ss" (eg.: "2008-03-09T16:05:07"")
    /// </summary>
    /// <param name="dateTime">target date time to convert to a string</param>
    /// <returns>dateTime formatted as a string</returns>
    public static string ToSortableFormatString(this DateTime dateTime)
    {
        string result = dateTime.ToString("s");
        return result;
    }

    /// <summary>
    /// Emits a result date time format string using a pattern that preserves
    /// time zone information and emits a result string that complies with
    /// ISO 8601 ("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"), preserves 
    /// the DateTime kind.
    /// </summary>
    /// <param name="dateTime">target date time to convert to a string</param>
    /// <returns>dateTime formatted as a string</returns>
    // 2009-06-15T13:45:30 (DateTimeKind.Utc) -->; 2009-06-15T13:45:30.0000000Z
    // 2009-06-15T13:45:30 (DateTimeKind.Local) --> 2009-06-15T13:45:30.0000000-07:00 (depending on the time zone)
    // 2009-06-15T13:45:30 (DateTimeKind.Unspecified) --> 2009-06-15T13:45:30.0000000
    public static string ToRoundTripFormatString(this DateTime dateTime)
    {
        string result = dateTime.ToString("o");
        return result;
    }

    static readonly string[] formats = { 
    // Extended formats
    "o",
    "yyyy-MM-ddTHH:mm:ss.ffffffZ",
    "yyyy-MM-ddTHH:mm:ss.fffffZ",
    "yyyy-MM-ddTHH:mm:ss.ffffZ",
    "yyyy-MM-ddTHH:mm:ss.fffZ",
    "yyyy-MM-ddTHH:mm:ss.ffZ",
    "yyyy-MM-ddTHH:mm:ss.fZ",
    "yyyy-MM-ddTHH:mm:ssZ"
  };

    public static DateTime ParseToIso8601DateTime(this string str)
    {
        return DateTime.ParseExact(str, formats,
            CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
    }

}

November 13, 2007

DateTime

Here are some links regarding DateTime string formatting and parsing: Truncating Milliseconds
private static DateTime TruncateMilliSeconds(DateTime dt)
{
  DateTime trunc = new DateTime(dt.Ticks - (10000*dt.Millisecond));
  Debug.Assert(trunc.Millisecond == 0);
  return trunc;
}
Parsing a date from a non standard form
DateTime.TryParseExact(dateStart, "yyyyMMdd",
  System.Globalization.CultureInfo.CurrentCulture,
  System.Globalization.DateTimeStyles.AssumeLocal, out m_StartDate);
Here is another example that will parse this string "Sun, 30 Jun 2013 14:14:01 +0100"
DateTime when = DateTime.MinValue;
string form = @"ddd, dd MMM yyyy HH':'mm':'ss K";
DateTime.TryParseExact(this.rawDateTime, form, 
  System.Globalization.CultureInfo.CurrentCulture,
  System.Globalization.DateTimeStyles.AssumeLocal, 
  out when);
Converting a date to a non standard string form
string datTimeStr = DateTime.UtcNow.ToString("yyyyMMdd"); 
where
M=month digit, y=year digit, d=day digit
h=hour digit (but H=24 hour digit), m=minute digit, s=second digit

Here is an example of this from renaming photos extracted from a digital camera
public class PhotoBackupOptions
{
    private string m_fileDateFormatStr = "yyyy_MMdd_HHmm";
    private string m_filenamePrefix = "Photo_";

    public string FileNameDateFormatStr
    {
        get { return m_fileDateFormatStr; }
    }

    public string FileNamePrefix
    {
        get { return m_filenamePrefix; }
    }

    public string GetPhotoFileName(FileInfo fsi)
    {
        Debug.Assert((fsi != null) && fsi.Exists);
        string res = fsi.Name;
        if (FileNameDateFormatStr.Length > 0)
        {
            DateTime dt = fsi.CreationTime;
            res = FileNamePrefix + 
                  dt.ToString(FileNameDateFormatStr) +
                  fsi.Extension;
        }
        return res;
    }
}
Here is a static method to load a date from a photo's metadata using WPF
// Retrieve the datetime from an image WITHOUT loading the whole thing
public static bool GetDateTakenFromImage(FileInfo fi, out DateTime dateTaken)
{
    dateTaken = DateTime.MinValue;
    bool found = false;
    try
    {
        using (FileStream fs = new FileStream(fi.FullName, 
            FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            BitmapMetadata md = (BitmapMetadata)BitmapFrame.Create(fs).Metadata;              
            found = DateTime.TryParse(md.DateTaken, out dateTaken);
        }
    }
    catch (Exception)
    {
        Trace.WriteLine("Could not get DateTaken from the image: \'" + fi.FullName + "\'");
    }
    return found;
}

August 18, 2005

My Testing Of DateTime Parsing Capabilities

  
  public static void TestDateTime()
  {
    TestDateParsing(DateTime.Today.ToString());
    TestDateParsing("16/08/2005");
    TestDateParsing("01-08-2005");
    TestDateParsing("25 December 2005");
    TestDateParsing("");
    TestDateParsing("YES");
    /*
Test with: '18/08/2005 00:00:00'
  '18/08/2005'
  Difference in days from today: 0
Test with: '16/08/2005'
  '16/08/2005'
  Difference in days from today: 2
  Date is WITHIN the last '21' days
Test with: '01-08-2005'
  '01/08/2005'
  Difference in days from today: 17
  Date is WITHIN the last '21' days
Test with: '25 December 2005'
  '25/12/2005'
  Difference in days from today: -128
Test with: ''
  Exception caught: 'String was not recognized as a valid DateTime.'
setting dat e to Minimum Value '01/01/0001' Difference in days from today: 732175 Test with: 'YES' Exception caught: 'The string was not recognized as a valid
DateTime. There i s a unknown word starting at index 0.' setting date to Minimum
Value '01/01/0001' Difference in days from today: 732175 */ } public static void TestDateParsing(string str) { DateTime date; try { WL(string.Concat("Test with: \'", str, "\'")); date = DateTime.Parse(str); } catch (Exception ex) { WL(string.Concat(" Exception caught: \'",ex.Message, "\'
setting date to Minimum Value")); date = DateTime.MinValue; } WL(string.Concat(" \'", date.ToString("dd/MM/yyyy"), "\'")); TimeSpan time = DateTime.Now.Subtract(date); WL(string.Concat(" Difference in days from today: ",time.Days)); const int DAYLIMIT = 21; if ((time.Days <= DAYLIMIT) && (time.Days > 0)) { WL(string.Concat(" Date is WITHIN the last \'", DAYLIMIT,
"\' days")); } }
To parse the string "Mon, 08 Apr 2013 09:56:56 +0100" had to use the parse format "ddd, dd MMM yyyy HH':'mm':'ss K"
Like so:
string form = @"ddd, dd MMM yyyy HH':'mm':'ss K";
DateTime.TryParseExact(pubDateNode.Value, form, 
  System.Globalization.CultureInfo.CurrentCulture,
  System.Globalization.DateTimeStyles.AssumeLocal, 
  out when);