使用 MongoDB java 驱动程序,在 Document 上应用 toJson() 方法将获得此文档的 JSON 表示形式,并将 JsonMode 设置为 STRICT。 以下纪元格式用于日期:{ "$date": "dateAsMilliseconds"}
使用 mongoexport,我们得到一个 ISO-8601 格式。
在官方文档 ( https://docs.mongodb.com/manual/reference/mongodb-extended-json/ ) 中看到:
在严格模式下,日期是一种 ISO-8601 日期格式,在模板 YYYY-MM-DDTHH:mm:ss.mmm<+ offset=""> 之后带有强制时区字段。
+>
MongoDB JSON 解析器目前不支持加载表示 Unix 纪元之前的日期的 ISO-8601 字符串。在格式化前纪元日期和超过系统 time_t 类型可以容纳的日期时,使用以下格式: { "$date": { "$numberLong": "dateAsMilliseconds"} }
如果有人能解释一下为什么 MongoDB java 驱动程序、mongoexport 工具和官方文档之间没有使用通用格式,我将不胜感激?
谢谢。
最佳答案
显然 没有 Java 驱动程序偏离官方规范的充分理由。唯一的异常(exception)是那些不能用 ISO8601 格式表示的日期(如 B.C. 日期......)
作为解决方法,我扩展了 JsonWriter 类并提供了两个 toJson 静态方法作为如何使用它的示例:
package whatever.package.you.like;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.bson.BSONException;
import org.bson.BsonContextType;
import org.bson.BsonDocument;
import org.bson.codecs.BsonDocumentCodec;
import org.bson.codecs.EncoderContext;
import org.bson.conversions.Bson;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriter;
import org.bson.json.JsonWriterSettings;
import com.mongodb.MongoClient;
/**
* A {@link JsonWriter} extension that conforms to the "strict" JSON format
* specified by MongoDB for data/time values.
*
* The {@link JsonWriter} class provided in the MongoDB Java driver (version
* 3.2.2) does not conform to official MongoDB specification for strict mode
* JSON (see https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
* This is specifically a problem with the date/time values which get filled
* with a milliseconds value (i.e. {$date: 309249234098}) instead of the ISO8601
* date/time (i.e. {$date: "2016-07-14T08:44:23.234Z"}) value which the
* specification calls for. This extension of {@link JsonWriter} conforms to the
* MongoDb specification in this regard.
*/
public class ConformingJsonWriter extends JsonWriter {
private final JsonWriterSettings settings;
private final Writer writer;
private boolean writingIndentedDateTime = false;
/**
* Creates a new instance which uses {@code writer} to write JSON to.
*
* @param writer
* the writer to write JSON to.
*/
public ConformingJsonWriter(final Writer writer) {
this(writer, new JsonWriterSettings());
}
/**
* Creates a new instance which uses {@code writer} to write JSON to and uses
* the given settings.
*
* @param writer
* the writer to write JSON to.
* @param settings
* the settings to apply to this writer.
*/
public ConformingJsonWriter(final Writer writer,
final JsonWriterSettings settings) {
super(writer, settings);
this.writer = writer;
this.settings = settings;
setContext(new Context(null, BsonContextType.TOP_LEVEL, ""));
}
private void writeIndentation(int skip) throws IOException {
for (Context context = getContext()
.getParentContext(); context != null; context = context
.getParentContext()) {
if (skip-- <= 0) {
writer.write(settings.getIndentCharacters());
}
}
}
private static String millisToIso8601(long millis) throws IOException {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(new Date(millis));
}
@Override
protected void doWriteDateTime(final long value) {
if ((settings.getOutputMode() == JsonMode.STRICT)
&& (value >= -59014396800000L && value <= 253399536000000L)) {
try {
writeStartDocument();
if (settings.isIndent()) {
writingIndentedDateTime = true;
writer.write(settings.getNewLineCharacters());
writeIndentation(0);
} else {
writer.write(" ");
}
writer.write("\"$date\" : ");
writer.write("\"");
writer.write(millisToIso8601(value));
writer.write("\"");
writeEndDocument();
writingIndentedDateTime = false;
} catch (IOException e) {
throw new BSONException("Wrapping IOException", e);
}
} else {
super.doWriteDateTime(value);
}
}
@Override
protected void doWriteEndDocument() {
if (writingIndentedDateTime) {
try {
writer.write(settings.getNewLineCharacters());
writeIndentation(1);
writer.write("}");
if (getContext()
.getContextType() == BsonContextType.SCOPE_DOCUMENT) {
setContext(getContext().getParentContext());
writeEndDocument();
} else {
setContext(getContext().getParentContext());
}
} catch (IOException e) {
throw new BSONException("Wrapping IOException", e);
}
} else {
super.doWriteEndDocument();
}
}
/**
* Take a {@link Bson} instance and convert it to "strict" JSON
* representation with no indentation (read, "NOT pretty printed").
*
* @param bson
* The {@link Bson} instance to convert
* @return The JSON representation.
*/
public static String toJson(Bson bson) {
return toJson(bson, new JsonWriterSettings());
}
/**
* Take a {@link Bson} instance and convert it to JSON representation.
*
* @param bson
* The {@link Bson} instance to convert
* @param writerSettings
* {@link JsonWriterSettings} that specify details about how the
* JSON output should look.
* @return The JSON representation.
*/
public static String toJson(Bson bson,
final JsonWriterSettings writerSettings) {
BsonDocumentCodec encoder = new BsonDocumentCodec();
ConformingJsonWriter writer = new ConformingJsonWriter(new StringWriter(),
writerSettings);
encoder.encode(writer,
bson.toBsonDocument(BsonDocument.class,
MongoClient.getDefaultCodecRegistry()),
EncoderContext.builder().isEncodingCollectibleDocument(true)
.build());
return writer.getWriter().toString();
}
}
关于json - 严格模式下的MongoDB日期格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38014515/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/
这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s