Click here to Skip to main content
15,561,681 members
Home / Discussions / C#
   

C#

 
AnswerRe: Sense of making my own Timestamp class? Pin
BillWoodruff4-Feb-14 4:56
professionalBillWoodruff4-Feb-14 4:56 
GeneralRe: Sense of making my own Timestamp class? Pin
Marco Bertschi4-Feb-14 5:03
professionalMarco Bertschi4-Feb-14 5:03 
AnswerRe: Sense of making my own Timestamp class? Pin
jschell4-Feb-14 14:20
jschell4-Feb-14 14:20 
GeneralRe: Sense of making my own Timestamp class? Pin
Marco Bertschi4-Feb-14 21:07
professionalMarco Bertschi4-Feb-14 21:07 
AnswerRe: Sense of making my own Timestamp class? Pin
TnTinMn6-Feb-14 13:37
TnTinMn6-Feb-14 13:37 
GeneralRe: Sense of making my own Timestamp class? Pin
Marco Bertschi6-Feb-14 22:12
professionalMarco Bertschi6-Feb-14 22:12 
GeneralRe: Sense of making my own Timestamp class? Pin
TnTinMn9-Feb-14 11:29
TnTinMn9-Feb-14 11:29 
GeneralRe: Sense of making my own Timestamp class? Pin
Marco Bertschi9-Feb-14 20:56
professionalMarco Bertschi9-Feb-14 20:56 
TnTinMn wrote:
You could use DateTime.TryParseExact with this format string: "yyyy-MM-dd\THH:mm:ss"

If that succeeds then, then you would need to extract the fractional second component (if it exists) as microseconds (upto 6 digits) and convert the microseconds to Ticks. Then you you can use the DateTime.AddTicks method on the DateTime value returned from the TryParseExact method.

Which is very difficult.
The biggest problem starts when you try to parse the Miliseconds directly, as in DateTime.TryParseExact(yyyy-MM-dd\THH:mm:ss.fff) where fff defines the miliseconds. DateTime can't handle any conversion if the amount of 'f' is not equal to the amount of the miliseconds, e.g.

parsing 2014-02-13\15:33:12.12 with DateTime.TryParseExact(yyyy-MM-dd\HH:mm:ss.fff) would return false, which is a crucial problem in my case since the amount of miliseconds may differ between 0 and 100000.
Of course I could populate them prior to the conversion, but then I am better of with my own class where I have full control over the conversion.


TnTinMn wrote:
I have put together a class to parse a TimeStamp string using this methodolgy and can make a copy of the code available if you are interested in it.

If you have it I'd love to see it. I have developed my own timestamp class a little further, here it is in case you are interested in it:

C#
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Springlog.Com.Messaging
{
    /// <summary>
    /// Represents the Timestamp of a <see cref="SyslogMessageHeader"/>
    /// Author: Marco Bertschi, (C) 2014 Marco Bertschi
    /// </summary>
    public class SyslogTimestamp
    {
        #region Properties
        /// <summary>
        /// Returns the count of the days for a specific month in a specific year.
        /// </summary>
        /// <param name="month">month  </param>
        /// <param name="year">year</param>
        /// <returns></returns>
        static short GetDayMaxDaysOfMonth(int month, int year)
        {
            if (month != 2)
            {
                //  January       March         May           July          August        October        December
                if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
                {
                    return 31;
                }
                else // April, June, September, November
                {
                    return 30;
                }
            }
            else //February
            {
                if (IsLeapYear(year))
                {
                    return 29;
                }
                return 28;
            }
        }
        /// <summary>
        /// Returns true if the argument is a leap year
        /// </summary>
        /// <param name="year">The year number to check</param>
        /// <returns></returns>
        private static bool IsLeapYear(int year)
        {
            if (year % 4 == 0)
            {
                if (year % 100 == 0)
                {
                    if (year % 400 == 0)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// The part of the Timestamp which represents the year.
        /// </summary>
        int year;
        /// <summary>
        /// Gets the year part of the Timestamp.
        /// </summary>
        public int Year
        {
            get { return year; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the month.
        /// </summary>
        int month;
        /// <summary>
        /// Gets the month part of the Timestamp.
        /// </summary>
        public int Month
        {
            get { return month; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the day of the month.
        /// </summary>
        int dayOfMonth;
        /// <summary>
        /// Gets the days part of the Timestamp.
        /// </summary>
        public int DayOfMonth
        {
            get { return dayOfMonth; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the hours.
        /// </summary>
        int hours;
        /// <summary>
        /// Gets the hours part of the Timestamp.
        /// </summary>
        public int Hours
        {
            get { return hours; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the minutes.
        /// </summary>
        int minutes;
        /// <summary>
        /// Gets the minutes part of the Timestamp.
        /// </summary>
        public int Minutes
        {
            get { return minutes; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the seconds.
        /// </summary>
        int seconds;
        /// <summary>
        /// Gets the seconds part of the Timestamp.
        /// </summary>
        public int Seconds
        {
            get { return seconds; }
        }
        /// <summary>
        /// The part of the Timestamp which represents the year.
        /// </summary>
        int miliseconds;
        /// <summary>
        /// Gets the milliseconds part of the Timestamp.
        /// </summary>
        public int Miliseconds
        {
            get { return miliseconds; }
        }
        /// <summary>
        /// The offset from the UTC timezone
        /// </summary>
        double utcOffset;
        /// <summary>
        /// Gets or sets the offset from the UTC timezone.
        /// </summary>
        public double UtcOffset
        {
            get { return utcOffset; }
            set { utcOffset = value; }
        }
        #endregion

        public SyslogTimestamp()
        {
            Reset();
        }

        public SyslogTimestamp(string timestamp)
        {
            Reset();
            FromString(timestamp);
        }

        public SyslogTimestamp(DateTime timestamp)
        {
            Reset();
            FromDateTime(timestamp);
        }

        /// <summary>
        /// Resets all fields to their default values;
        /// </summary>
        private void Reset()
        {
            miliseconds = 0;
            seconds = 0;
            minutes = 0;
            hours = 0;
            dayOfMonth = 0;
            month = 0;
            year = 0;
            utcOffset = 0;
        }

        /// <summary>
        /// Parses a string into a Syslog timestamp.
        /// </summary>
        /// <param name="dateTime">string which is going to be parsed</param>
        /// <returns>true = success | false = invalid string</returns>
        public bool FromString(string dateTime)
        {
            Reset();// All fields must be resetted - Otherwise the parsing will give a wrong value!
            Regex splitRegex = new Regex(@"(\d{4})-(0?[1-9]|1[0-2])-([0-2]?\d|3[0-1])T?([0-1]?\d|2[0-3]):([0-5]?\d):([0-5]?\d)\.?(\d{0,6})?Z?([+-]?\d\.?\d?|\d{2}?|[0]?1[0-2]\.?\d?|\d{2}?)?", RegexOptions.IgnoreCase);
            Match timestamp = splitRegex.Match(dateTime);

            if (timestamp.Groups.Count == 9)
            {
                AddYears(Int32.Parse(timestamp.Groups[1].Value));
                AddMonths(Int32.Parse(timestamp.Groups[2].Value));
                AddDays(Int32.Parse(timestamp.Groups[3].Value));
                AddHours(Int32.Parse(timestamp.Groups[4].Value));
                AddMinutes(Int32.Parse(timestamp.Groups[5].Value));
                AddSeconds(Int32.Parse(timestamp.Groups[6].Value));
                if (!string.IsNullOrWhiteSpace(timestamp.Groups[7].Value))
                {
                    AddMilliseconds(Int32.Parse(timestamp.Groups[7].Value));
                }
                if (!string.IsNullOrWhiteSpace(timestamp.Groups[8].Value))
                {
                    utcOffset = Double.Parse(timestamp.Groups[8].Value, CultureInfo.InvariantCulture);
                }
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Returns a fully formatted Syslog timestamp, as string.
        /// </summary>
        /// <returns>Syslog timestamp, as string</returns>
        public string ToFormattedString()
        {
            string timezonePreSign = "Z";
            if (utcOffset < 0)
            {
                timezonePreSign = "";
            }
            return string.Format("{0}-{1}-{2}T{3}:{4}:{5}.{6}{7}{8}", year, month, dayOfMonth, hours, minutes, seconds, miliseconds, timezonePreSign, utcOffset.ToString().Replace(',','.'));
        }

        public DateTime ToDateTime()
        {
            DateTimeKind dateTimeKind;
            if(utcOffset == 0)
            {
                dateTimeKind = DateTimeKind.Utc;
            }
            else
            {
                dateTimeKind = DateTimeKind.Local;
            }
            return new DateTime(year, month, dayOfMonth, hours, minutes, seconds, miliseconds, dateTimeKind);
        }

        /// <summary>
        /// Overriden ToString() method - Displays the same as ToFormattedString().
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.ToFormattedString();
        }
        /// <summary>
        /// Parses a <see cref="System.DateTime"/> type to a <see cref="SyslogTimestamp"/>. It is assumed that the
        /// DateTime type must be converted to UTC if the second argument is left out.
        /// </summary>
        /// <remarks>
        /// The FromDateTime method recognizes only the current daylight saving time adjustment rule for the local time zone.
        /// As a result, it is guaranteed to accurately return the UTC offset of a local time only during the period in which the
        /// latest adjustment rule is in effect. It may return inaccurate results if time is a historic date and time value
        /// that was subject to a previous adjustment rule.
        /// </remarks>
        /// <param name="timestamp">The <see cref="System.DateTime"/> type which will be parsed</param>
        public void FromDateTime(DateTime timestamp)
        {
            TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(timestamp);
            this.utcOffset = utcOffset.Hours + (utcOffset.Minutes / 100);

            AddMilliseconds(timestamp.Millisecond);
            AddSeconds(timestamp.Second);
            AddMinutes(timestamp.Minute);
            AddHours(timestamp.Hour);
            AddDays(timestamp.Day);
            AddMonths(timestamp.Month);
            AddYears(timestamp.Year);
        }

        /// <summary>
        /// Adds a <see cref="System.TimeSpan"/> to the timestamp
        /// </summary>
        /// <param name="timeSpan">The time span which is added to the Timestamp</param>
        public void Add(TimeSpan timeSpan)
        {
            AddMilliseconds(timeSpan.Milliseconds);
            AddSeconds(timeSpan.Seconds);
            AddMinutes(timeSpan.Minutes);
            AddHours(timeSpan.Hours);
            AddDays(timeSpan.Days);
        }
        /// <summary>
        /// Adds the passed millisecond value to the timestamp
        /// </summary>
        /// <param name="val">Added milliseconds</param>
        public void AddMilliseconds(int val)
        {
            if (val + miliseconds >= 1000)
            {
                AddSeconds( val / 1000);
                miliseconds = (val % 1000);
            }
            else
            {
                miliseconds += val;
            }
        }
        /// <summary>
        /// Adds the passed second value to the timestamp
        /// </summary>
        /// <param name="val">Added seconds</param>
        private void AddSeconds(int val)
        {
            if (seconds + val >= 60)
            {
                AddMinutes(val / 60);
                seconds = (val % 60);
            }
            else
            {
                seconds += val;
            }
        }
        /// <summary>
        /// Adds the passed minute value to the timestamp
        /// </summary>
        /// <param name="val">Added minutes</param>
        private void AddMinutes(int val)
        {
            if (minutes + val >= 60)
            {
                AddMinutes(val / 60);
                minutes = (val % 60);
            }
            else
            {
                minutes += val;
            }
        }
        /// <summary>
        /// Adds the passed hour value to the timestamp
        /// </summary>
        /// <param name="val">Added hours</param>
        private void AddHours(int val)
        {
            if (hours + val >= 24)
            {
                AddDays (val / 24);
                hours = (val % 24);
            }
            else
            {
                hours += val;
            }
        }
        /// <summary>
        /// Adds the passed days value to the timestamp
        /// </summary>
        /// <param name="val">Added days</param>
        private void AddDays(int val)
        {
            short dayCount = GetDayMaxDaysOfMonth(month, year);
            if (dayOfMonth + val > dayCount)
            {
                AddMonths(val / dayCount);
                dayOfMonth = (val % dayCount);
            }
            else
            {
                dayOfMonth += val;
            }
        }
        /// <summary>
        /// Adds the passed month value to the timestamp
        /// </summary>
        /// <param name="val">Added months</param>
        private void AddMonths(int val)
        {
            if (month + val > 12)
            {
                AddYears(val / 12);
                month = (val % 12);
            }
            else
            {
                month += val;
            }
        }
        /// <summary>
        /// Adds the passed value to the year part of the time stamp
        /// </summary>
        /// <param name="val">Years to be added</param>
        private void AddYears(int val)
        {
            year += val;
        }

        /// <summary>
        /// Returns true if the the parameter matches this instance.
        /// </summary>
        /// <remarks>
        /// See <see cref="DoMatch"/>
        /// </remarks>
        /// <param name="other">The parameter to compare</param>
        /// <returns>true|false</returns>
        public override bool Equals(object o)
        {
            if (o is SyslogTimestamp)
            {
                return DoMatch((SyslogTimestamp)o, this);
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Returns true if a & b match, else false.
        /// </summary>
        /// <remarks>
        /// Match criteria:
        /// (a.year == b.Year)
        /// && (a.month == b.Month)
        /// && (a.dayOfMonth == b.DayOfMonth)
        /// && (a.hours == b.Hours)
        /// && (a.minutes == b.Minutes)
        /// && (a.seconds == b.Seconds)
        /// && (a.miliseconds == b.Miliseconds)
        /// && (a.utcOffset == b.UtcOffset);
        /// </remarks>
        public static bool DoMatch(SyslogTimestamp a, SyslogTimestamp b)
        {
            bool doMatch = (a.year == b.Year)
                && (a.month == b.Month)
                && (a.dayOfMonth == b.DayOfMonth)
                && (a.hours == b.Hours)
                && (a.minutes == b.Minutes)
                && (a.seconds == b.Seconds)
                && (a.miliseconds == b.Miliseconds)
                && (a.utcOffset == b.UtcOffset);

            return doMatch;
        }
        /// <summary>
        /// The overloaded == operator
        /// </summary>
        /// <remarks>
        /// see http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx
        /// </remarks>
        public static bool operator ==(SyslogTimestamp a, SyslogTimestamp b)
        {
            // If both are null, or both are same instance, return true.
            if (System.Object.ReferenceEquals(a, b))
            {
                return true;
            }

            // If one is null, but not both, return false.
            if (((object)a == null) || ((object)b == null))
            {
                return false;
            }

            return DoMatch(a, b);
        }
        /// <summary>
        /// The overloaded != operator.
        /// </summary>
        /// <remarks>
        /// see http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx
        /// </remarks>
        public static bool operator !=(SyslogTimestamp a, SyslogTimestamp b)
        {
            return !(a == b);
        }
        /// <summary>
        /// The smaller than Operator
        /// compares every date|time related field with
        /// the other and returns true if the left hand side of
        /// the assignement is smaller than the right hand side
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator <(SyslogTimestamp a, SyslogTimestamp b)
        {
            if (a.Year < b.Year) { return true; }
            if (a.Year > b.Year) { return false; }

            if (a.Month < b.Month) { return true; }
            if (a.Month > b.Month) { return false; }

            if (a.DayOfMonth < b.DayOfMonth) { return true; }
            if (a.DayOfMonth > b.DayOfMonth) { return false; }

            if ((a.Hours + a.UtcOffset) < (b.Hours + b.UtcOffset)) { return true; }
            if ((a.Hours + a.UtcOffset) > (b.Hours + b.UtcOffset)) { return false; }

            if (a.Minutes < b.Minutes) { return true; }
            if (a.Minutes > b.Minutes) { return false; }

            if (a.Seconds < b.Seconds) { return true; }
            if (a.Seconds > b.Seconds) { return false; }

            if (a.Miliseconds < b.Miliseconds) { return true; }
            if (a.Miliseconds > b.Miliseconds) { return false; }

            return false;
        }
        /// <summary>
        /// The greater than Operator
        /// compares every date|time related field with
        /// the other and returns true if the left hand side of
        /// the assignement is greater than the right hand side
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator >(SyslogTimestamp a, SyslogTimestamp b)
        {
            if (a.Year > b.Year) { return true; }
            if (a.Year < b.Year) { return false; }

            if (a.Month > b.Month) { return true; }
            if (a.Month < b.Month) { return false; }

            if (a.DayOfMonth > b.DayOfMonth) { return true; }
            if (a.DayOfMonth < b.DayOfMonth) { return false; }

            if ((a.Hours + a.UtcOffset) > (b.Hours + b.UtcOffset)) { return true; }
            if ((a.Hours + a.UtcOffset) < (b.Hours + b.UtcOffset)) { return false; }

            if (a.Minutes > b.Minutes) { return true; }
            if (a.Minutes < b.Minutes) { return false; }

            if (a.Seconds > b.Seconds) { return true; }
            if (a.Seconds < b.Seconds) { return false; }

            if (a.Miliseconds > b.Miliseconds) { return true; }
            if (a.Miliseconds < b.Miliseconds) { return false; }

            return false;
        }
        /// <summary>
        /// greater or equal Operator
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns>(a > b) || DoMatch(a, b)</returns>
        public static bool operator >=(SyslogTimestamp a, SyslogTimestamp b)
        {
            return (a > b) || DoMatch(a, b);
        }
        /// <summary>
        /// smaller or equal Operator
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns><code>(a { b) || DoMatch(a, b)</code></returns>
        public static bool operator <=(SyslogTimestamp a, SyslogTimestamp b)
        {
            return (a < b) || DoMatch(a, b);
        }

        /// <summary>
        /// Returns the Hash code of the object
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}

Clean-up crew needed, grammar spill... - Nagy Vilmos

GeneralRe: Sense of making my own Timestamp class? Pin
TnTinMn10-Feb-14 14:12
TnTinMn10-Feb-14 14:12 
QuestionSSIS for Fixed Length line Pin
nitin_ion3-Feb-14 21:26
nitin_ion3-Feb-14 21:26 
AnswerRe: SSIS for Fixed Length line Pin
Bernhard Hiller3-Feb-14 21:52
Bernhard Hiller3-Feb-14 21:52 
GeneralRe: SSIS for Fixed Length line Pin
Marco Bertschi3-Feb-14 21:56
professionalMarco Bertschi3-Feb-14 21:56 
GeneralRe: SSIS for Fixed Length line Pin
nitin_ion3-Feb-14 22:46
nitin_ion3-Feb-14 22:46 
QuestionCreating barcode of type ean-13 in c# windows forms with sql server 2008 using StrokeScribe control of version 4.3.2 Pin
Member 102487683-Feb-14 20:00
Member 102487683-Feb-14 20:00 
SuggestionRe: Creating barcode of type ean-13 in c# windows forms with sql server 2008 using StrokeScribe control of version 4.3.2 Pin
Richard MacCutchan3-Feb-14 22:53
mveRichard MacCutchan3-Feb-14 22:53 
QuestionNorth wind Database Pin
Sandhya Bandar3-Feb-14 10:46
Sandhya Bandar3-Feb-14 10:46 
AnswerRe: North wind Database Pin
Kornfeld Eliyahu Peter3-Feb-14 10:54
professionalKornfeld Eliyahu Peter3-Feb-14 10:54 
AnswerRe: North wind Database Pin
Dave Kreskowiak3-Feb-14 13:49
mveDave Kreskowiak3-Feb-14 13:49 
JokeRe: North wind Database Pin
Kornfeld Eliyahu Peter3-Feb-14 21:19
professionalKornfeld Eliyahu Peter3-Feb-14 21:19 
AnswerRe: North wind Database Pin
Marco Bertschi3-Feb-14 22:04
professionalMarco Bertschi3-Feb-14 22:04 
QuestionWorking with Bitmaps Pin
BBatts3-Feb-14 8:45
BBatts3-Feb-14 8:45 
AnswerRe: Working with Bitmaps Pin
TnTinMn4-Feb-14 7:56
TnTinMn4-Feb-14 7:56 
QuestionProject Question Pin
reaper21913-Feb-14 6:15
reaper21913-Feb-14 6:15 
AnswerRe: Project Question Pin
Alan Balkany3-Feb-14 6:20
Alan Balkany3-Feb-14 6:20 
AnswerRe: Project Question Pin
Pete O'Hanlon3-Feb-14 6:48
mvaPete O'Hanlon3-Feb-14 6:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.