2

I need to generate the current Date in vb.net that's have also the millisecond. Actually I use:

Date.Now

But this returns a simple date as 28/12/2015 16:53, I want also the millisecond something like:

28/12/2015 16:53:48640864

I tried with:

Public Shared Function MillisecondsDate()

    Return Date.Now.ToString("HH:mm:ss.fffffff")

End Function

but this returns a bad result:

16:53:56.9884043

I need a format compatible with MySql for an accurate lastUpdated field. Any ideas?

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
Sandokan
  • 1,075
  • 3
  • 15
  • 30
  • 4
    Maybe this http://stackoverflow.com/questions/16032451/get-datetime-now-with-milliseconds-precision – J3soon Dec 28 '15 at 15:59
  • Okay but with a DateTime structure in vb.net I lost the milliseconds, maybe this is a timestamp? – Sandokan Dec 28 '15 at 16:00
  • 1
    Shouldnt the lastupdated field be on a trigger (in which case MySQL will handle it)? The DateTime type always has the Date and Time parts including millisecs. If you dont see them, it is just the way it is being displayed. Also turn on Option Strict – Ňɏssa Pøngjǣrdenlarp Dec 28 '15 at 16:02
  • I've option strict enabled, anyway, the date is returned correctly as in the answers below, but I get in my db this: 0000-00-00 00:00:00, my db field is a timestamp. – Sandokan Dec 28 '15 at 16:08
  • I fix temp using a varchar instead a datetime or timestamp. But I guess is not a good practice. – Sandokan Dec 28 '15 at 16:14
  • 1
    Note that this is not a dupe of the one proposed. It was worded a little badly. The problem was not **getting** milliseconds, but not loosing them when a DateTime was saved to the database. – Ňɏssa Pøngjǣrdenlarp Dec 29 '15 at 17:49

3 Answers3

4

From comments: my db field is a timestamp and I fix temp using a varchar instead a datetime or timestamp

A TimeStamp column isnt quite the same as a DateTime column. According to the Documentation:

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)

It is something you may never see, even MySQL WorkBench UI converts it back.

Fractional Seconds

The issue of Fractional Seconds is something else. When defining a column as DateTime or TimeStamp, fractional seconds are dropped by default, for compatibility with older versions.

Rather than defining any sort of Date column as string/text/varchar - and of course having to parse it back - you can define either type to retain fractional seconds. In MySQL 5.6.4+, you can use: DATETIME(n) or TIMESTAMP(n) (yes, thats why the parens show in the UI dropdown list). Where n is the number of fractional digits to store (0-6). For .NET, 3 would equate to milliseconds. After that, the WorkBench UI shows the milliseconds as well:

enter image description here

  • StartDate is DateTime(0) (no fractionals)
  • LastUpdated is TimeStamp(3)
  • Foo is TimeStamp(6)

Trigger

A LastUpdated column would seem best managed by the database so you don't have to do so via code -- or forget to do so!. This is pretty simple using a default value and a Before_Update trigger:

  • Define the column as TIMESTAMP(3)
  • Specify CURRENT_TIMESTAMP(3) as the default value

ADD COLUMN LastUpdated TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '';

This would automatically set the LastUpdated value on new items added to the current time (UTC etc) with milliseconds (TIMESTAMP(6) might be better, but the question only frets about ms). Be sure to specify the same number of digits in the default.

Then, rather than passing DateTime.Now manually (or converting to string) when updating each record, add a trigger to update the column for you. In MySql Workbench:

CREATE DEFINER=`root`@`localhost` TRIGGER `test`.`demo_BEFORE_INSERT` BEFORE INSERT ON `demo` FOR EACH ROW  
BEGIN  
    SET new.LastUpdated := now(3);  
END 

Most of that is boilerplate that the UI Tool creates. You just need to type:

    SET new.LastUpdated := now(3);  

For this type of column, you'd can add the same thing on the BEFORE_INSERT trigger in place of a default value. In MySQL WorkBench, click the "Triggers" tab when viewing the table definitions - just add the SET statement.

Test Code

This shows the fractional milliseconds making the round trip from code to db and back, and shows that the trigger works (uses the table shown above):

Dim Usql = "UPDATE Demo SET Foo = @p1 WHERE Id=5"
Dim Ssql = "SELECT Name, StartDate, Foo, LastUpdated FROM Demo WHERE Id=5"

Dim dtVar As DateTime = DateTime.Now
Console.WriteLine("DT ms in code var: {0}", dtVar.Millisecond)

Using dbcon = GetMySQLConnection()
    dbcon.Open()
    Using cmd As New MySqlCommand(Usql, dbcon)
        cmd.Parameters.AddWithValue("@p1", dtVar)
        cmd.ExecuteNonQuery()
    End Using

    Using cmd As New MySqlCommand(Ssql, dbcon)
        Using rdr As MySqlDataReader = cmd.ExecuteReader
            If rdr.HasRows Then
                rdr.Read()

                Dim tempDT = rdr.GetMySqlDateTime(1)    ' DateTime(0)
                Console.WriteLine("DT.MS from DB {0}", tempDT.Millisecond)

                Dim mydt = rdr.GetMySqlDateTime(2)    ' TimeStamp(6)
                Console.WriteLine("Micro from DB {0} ", mydt.Microsecond)

                ' either get method retains the ms      TimeStamp(3)
                Dim lstupD = Convert.ToDateTime(rdr("lastUpdated"))
                Console.WriteLine("MS from trigger {0}", lstupD.Millisecond)
            End If
        End Using
    End Using
End Using

Result:

DT ms in code var: 615
DT.MS from DB 0
Micro from DB 615413
MS from trigger 615

The columns defined to store fractional seconds do so down to microseconds (ticks). Note that the Update SQL doesn't reference the LastUpdated column, yet it is updated courtesy of the trigger. If you are step-debugging and using a variable as above the trigger time can vary from the others because time is passing as you step through.

Community
  • 1
  • 1
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • We can also make this, so that on the update of the record, LastUpdated will update the value. No additional Trigger query is required ```ADD COLUMN LastUpdated TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)``` – Hassan Mudassir Sep 26 '19 at 06:18
0

Try this

Public Shared Function MillisecondsDate()

    Return Date.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")
End Function
J3soon
  • 3,013
  • 2
  • 29
  • 49
-1

Try this function:

Public Shared Function MillisecondsDate()
    Return DateTime.UtcNow.ToString("dd/MM/yyyy HH:mm:ss.fff")
End Function
meda
  • 45,103
  • 14
  • 92
  • 122
  • The time now is returned correctly but in my db I get this: 0000-00-00 00:00:00, maybe the timestamp is not a good choice? – Sandokan Dec 28 '15 at 16:05
  • @Sandokan for `28/12/2015 16:53:48640864` you need to adjust the format to `dd/MM/yyyy HH:mm:ss.fff` – meda Dec 28 '15 at 16:18
  • I don't know about MySQL but you are right that timestamp is not the correct choice for MS SQL. Use datetime. Timestamp is a weird creature not intended for storing user data. – rheitzman Dec 28 '15 at 17:41
  • @J3soon, Yes its almost the same, but it is not the same. And you both answered it at about the same time. The OP can chose any answer as the correct one ! – Rohit Gupta Dec 29 '15 at 10:13
  • @RohitGupta yes but the correct format to this answer should be `dd/MM/yyyy HH:mm:ss.fff` as @Sandokan preferred – J3soon Dec 29 '15 at 10:18
  • @J3soon, that has nothing to do with it. The OP ticks the answer that works for him. It has nothing to do with what is the best answer. The best answer is voted by other users. It is early days yet, but so far, the third answer has the most votes. Because it is has substance. I suggested to you to update your answer with more meat. But you haven't done it. – Rohit Gupta Dec 29 '15 at 10:22