【问题标题】:How to save and retain Date milliseconds (MySQL)如何保存和保留日期毫秒(MySQL)
【发布时间】:2015-12-28 15:58:03
【问题描述】:

我需要在 vb.net 中生成当前日期,该日期也有毫秒。其实我用:

Date.Now

但这会返回一个简单的日期,如 28/12/2015 16:53,我还想要毫秒:

28/12/2015 16:53:48640864

我试过了:

Public Shared Function MillisecondsDate()

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

End Function

但这会返回一个错误的结果:

16:53:56.9884043

我需要一种与MySql 兼容的格式,以获得准确的lastUpdated 字段。有什么想法吗?

【问题讨论】:

  • 好的,但是在 vb.net 中使用 DateTime 结构我丢失了毫秒,也许这是一个时间戳?
  • lastupdated 字段是否应该在触发器上(在这种情况下 MySQL 会处理它)? DateTime 类型始终具有日期和时间部分,包括毫秒。如果您没有看到它们,那只是它的显示方式。同时开启 Option Strict
  • 我已经启用了严格选项,无论如何,日期在下面的答案中正确返回,但我在我的数据库中得到这个:0000-00-00 00:00:00,我的数据库字段是一个时间戳。
  • 请注意,这不是所提议的欺骗。它的措辞有点糟糕。问题不是 得到 毫秒,而是在将 DateTime 保存到数据库时没有丢失它们。

标签: mysql .net vb.net


【解决方案1】:

来自 cmets:my db field is a timestampI fix temp using a varchar instead a datetime or timestamp

TimeStamp 列与DateTime 列并不完全相同。根据Documentation

MySQL 将 TIMESTAMP 值从当前时区转换为 UTC 进行存储,并从 UTC 转换回当前时区进行检索。 (这不会发生在其他类型,例如 DATETIME。)

这是您可能永远看不到的东西,即使是 MySQL WorkBench UI 也会将其转换回来。

小数秒

Fractional Seconds 的问题是另外一回事。将列定义为 DateTimeTimeStamp 时,默认情况下会删除小数秒,以便与旧版本兼容。

而不是将任何类型的Date 列定义为字符串/文本/varchar - 当然必须将其解析回来 - 您可以定义任一类型以保留小数秒。在 MySQL 5.6.4+ 中,您可以使用:DATETIME(n)TIMESTAMP(n)(是的,那就是为什么括号会显示在 UI 下拉列表中)。其中n 是要存储的小数位数 (0-6)。对于 .NET,3 相当于毫秒。之后,WorkBench UI 也会显示毫秒数:

  • StartDate 为 DateTime(0)(无小数)
  • 上次更新时间为TimeStamp(3)
  • Foo 是TimeStamp(6)

触发器

LastUpdated 列似乎最好由数据库管理,因此您不必通过代码来管理 - 或者 忘记 这样做!。使用默认值和Before_Update 触发器非常简单:

  • 将列定义为TIMESTAMP(3)
  • CURRENT_TIMESTAMP(3)指定为默认值

添加列LastUpdatedTIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '';

这将自动为添加到当前时间(UTC 等)的新项目设置 LastUpdated 值,以毫秒为单位(TIMESTAMP(6) 可能更好,但问题只关心毫秒)。请务必在默认中指定相同的位数。

然后,在更新每条记录时,不要手动传递DateTime.Now(或转换为字符串),而是添加一个触发器来为您更新列。在 MySql 工作台中:

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

其中大部分是 UI 工具创建的样板。您只需输入:

    SET new.LastUpdated := now(3);  

对于这种类型的列,您可以在 BEFORE_INSERT 触发器上添加相同的内容来代替默认值。在 MySQL WorkBench 中,查看表定义时单击“触发器”选项卡 - 只需添加 SET 语句。

测试代码

这显示了从代码到数据库并返回的往返时间的小数毫秒,并显示触发器工作(使用上面显示的表格):

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

结果:

代码变量中的 DT ms:615
来自 DB 0 的 DT.MS
来自 DB 615413 的微型
触发 615 的 MS

定义为存储小数秒的列可以精确到微秒(滴答声)。请注意,更新 SQL 没有引用 LastUpdated 列,但它是由触发器更新的。如果您正在逐步调试并使用上述变量,则触发时间可能与其他变量有所不同,因为时间会随着您逐步进行而流逝。

【讨论】:

  • 我们也可以这样做,这样在更新记录时,LastUpdated 会更新值。不需要额外的触发器查询ADD COLUMN LastUpdated TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
【解决方案2】:

试试这个

Public Shared Function MillisecondsDate()

    Return Date.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")
End Function

【讨论】:

  • dd -> 当前日期。 MM -> 当前月份。 yyyy -> 当前年份
【解决方案3】:

试试这个功能:

Public Shared Function MillisecondsDate()
    Return DateTime.UtcNow.ToString("dd/MM/yyyy HH:mm:ss.fff")
End Function

【讨论】:

  • 现在时间返回正确但在我的数据库中我得到这个:0000-00-00 00:00:00,也许时间戳不是一个好的选择?
  • @Sandokan for 28/12/2015 16:53:48640864 你需要将格式调整为dd/MM/yyyy HH:mm:ss.fff
  • 我不了解 MySQL,但您说得对,时间戳不是 MS SQL 的正确选择。使用日期时间。 Timestamp 是一种奇怪的生物,并非用于存储用户数据。
  • @J3soon,是的,几乎一样,但不一样。你们几乎同时回答了这个问题。 OP可以选择任何答案作为正确答案!
  • @RohitGupta 是的,但是这个答案的正确格式应该是 dd/MM/yyyy HH:mm:ss.fff @Sandokan 首选
猜你喜欢
  • 2011-09-06
  • 1970-01-01
  • 2020-12-12
  • 2020-04-10
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 2019-04-17
  • 2018-08-05
相关资源
最近更新 更多