草庐IT

database - 在 Go 中以及可能在其他语言和其他数据库中比较 mongodb 驱动程序的时间精度问题

coder 2024-07-12 原文

我正在学习 Go 和 Mongodb,目前正在使用 alpha official mongodb driver .虽然它处于 alpha 阶段,但我认为它对于基本用法来说非常实用。 但是我在这个数据库驱动程序中遇到了一个关于时间转换的有趣问题。

基本上,我创建了一个自定义类型的结构对象,并将其编码为 bson 文档,然后将 bson 文档转换回结构对象。

//check github.com/mongodb/mongo-go-driver/blob/master/bson/marshal_test.go
func TestUserStructToBsonAndBackwards(t *testing.T) {
u := user{
    Username:          "test_bson_username",
    Password:          "1234",
    UserAccessibility: "normal",
    RegisterationTime: time.Now(), //.Format(time.RFC3339), adding format result a string
}

//Struct To Bson
bsonByteArray, err := bson.Marshal(u)
if err != nil {
    t.Error(err)
}
//.UnmarshalDocument is the same as ReadDocument
bDoc, err := bson.UnmarshalDocument(bsonByteArray)
if err != nil {
    t.Error(err)
}
unameFromBson, err := bDoc.LookupErr("username")
//so here the binding is working for bson object too, the bind field named username ratherthan Username
if err != nil {
    t.Error(err)
}
if unameFromBson.StringValue() != "test_bson_username" {
    t.Error("bson from user struct Error")
}

//Bson Doc to User struct
bsonByteArrayFromDoc, err := bDoc.MarshalBSON()
if err != nil {
    t.Error(err)
}

var newU user
err = bson.Unmarshal(bsonByteArrayFromDoc, &newU)
if err != nil {
    t.Error(err)
}

if newU.Username != u.Username {
    t.Error("bson Doc to user struct Error")
}

//here we have an issue about time format.
if newU != u {
    log.Println(newU)
    log.Println(u)
    t.Error("bson Doc to user struct time Error")
}
}

但是由于我的结构对象有一个时间字段,结果结构对象包含的时间值不如原始时间值准确。那么比较失败。

=== RUN   TestUserStructToBsonAndBackwards
{test_bson_username 1234     0001-01-01 00:00:00 +0000 UTC   2018-08-28 23:56:50.006 +0800 CST 0001-01-01 00:00:00 +0000 UTC normal }
{test_bson_username 1234     0001-01-01 00:00:00 +0000 UTC   2018-08-28 23:56:50.006395949 +0800 CST m=+0.111119920 0001-01-01 00:00:00 +0000 UTC normal }
--- FAIL: TestUserStructToBsonAndBackwards (0.00s)
    model.user_test.go:67: bson Doc to user struct time Error

所以我想从这里问很多问题。

  1. 在这种情况下如何正确比较时间?

  2. 在数据库中存储时间以避免此类精度问题的最佳方法是什么?我认为数据库中的时间不应该是一个字符串。

  3. 这是数据库驱动程序错误吗?

最佳答案

BSON 中的时间表示为自 Unix 纪元 (spec) 以来的 UTC 毫秒数。 Go 中的时间值具有纳秒精度。

往返时间。通过 BSON 编码的时间值,使用自 Unix 纪元以来截断为毫秒的时间:

func truncate(t time.Time) time.Time {
    return time.Unix(0, t.UnixNano()/1e6*1e6)
}

...

u := user{
    Username:          "test_bson_username",
    Password:          "1234",
    UserAccessibility: "normal",
    RegisterationTime: truncate(time.Now()), 
}

您还可以使用 Time.Truncate方法:

u := user{
    Username:          "test_bson_username",
    Password:          "1234",
    UserAccessibility: "normal",
    RegisterationTime:  time.Now().Truncate(time.Millisecond),
}

这种方法依赖于 Unix 纪元和 Go 零时间相差整数毫秒这一事实。

关于database - 在 Go 中以及可能在其他语言和其他数据库中比较 mongodb 驱动程序的时间精度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52061986/

有关database - 在 Go 中以及可能在其他语言和其他数据库中比较 mongodb 驱动程序的时间精度问题的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  5. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  6. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  7. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  8. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  9. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐