forked from Automattic/mongoose
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdates.html
More file actions
159 lines (145 loc) · 16.9 KB
/
dates.html
File metadata and controls
159 lines (145 loc) · 16.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Mongoose v5.6.4-pre: Mongoose Tutorials: Working With Dates</title><link rel="apple-touch-icon" sizes="57x57" href="images/favicon/apple-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="images/favicon/apple-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="images/favicon/apple-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="images/favicon/apple-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="images/favicon/apple-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="images/favicon/apple-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="images/favicon/apple-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="images/favicon/apple-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="images/favicon/apple-icon-180x180.png"><link rel="icon" type="image/png" sizes="192x192" href="images/favicon/android-icon-192x192.png"><link rel="icon" type="image/png" sizes="32x32" href="images/favicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="96x96" href="images/favicon/favicon-96x96.png"><link rel="icon" type="image/png" sizes="16x16" href="images/favicon/favicon-16x16.png"><link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"><link rel="stylesheet" href="/docs/css/github.css"><link rel="stylesheet" href="/docs/css/mongoose5.css"><link rel="apple-touch-icon" sizes="57x57" href="images/favicon/apple-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="images/favicon/apple-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="images/favicon/apple-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="images/favicon/apple-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="images/favicon/apple-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="images/favicon/apple-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="images/favicon/apple-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="images/favicon/apple-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="images/favicon/apple-icon-180x180.png"><link rel="icon" type="image/png" sizes="192x192" href="images/favicon/android-icon-192x192.png"><link rel="icon" type="image/png" sizes="32x32" href="images/favicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="96x96" href="images/favicon/favicon-96x96.png"><link rel="icon" type="image/png" sizes="16x16" href="images/favicon/favicon-16x16.png"><link rel="manifest" href="images/favicon/manifest.json"><meta name="msapplication-TileColor" content="#ffffff"><meta name="msapplication-TileImage" content="images/favicon/ms-icon-144x144.png"><meta name="theme-color" content="#ffffff"><link rel="stylesheet" href="/docs/css/inlinecpc.css"><script type="text/javascript" src="/docs/js/native.js"></script><style>p { line-height: 1.5em }
</style></head><body><div id="layout"><div id="mobile-menu"><a class="menu-link" id="menuLink" href="#menu"><span></span></a><div id="mobile-logo-container"><a href="/"><img id="logo" src="/docs/images/mongoose5_62x30_transparent.png"><span class="logo-text">mongoose</span></a></div></div><div id="menu"><div class="pure-menu"><div class="pure-menu-heading" id="logo-container"><a href="/"><img id="logo" src="/docs/images/mongoose5_62x30_transparent.png"><span class="logo-text">mongoose</span></a></div><ul class="pure-menu-list" id="navbar"><li class="pure-menu-horizontal pure-menu-item pure-menu-has-children pure-menu-allow-hover version"><a class="pure-menu-link" href="#">Version 5.6.4-pre</a><ul class="pure-menu-children"><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/4.x">Version 4.13.19</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/3.8.x">Version 3.8.40</a></li></ul></li><li class="pure-menu-item search"><input id="search-input-nav" type="text" placeholder="Search"><button id="search-button-nav"><img src="/docs/images/search.svg"></button></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/index.html">Quick Start</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/guides.html">Guides</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/guide.html">Schemas</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/schematypes.html">SchemaTypes</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/connections.html">Connections</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/models.html">Models</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/documents.html">Documents</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/subdocs.html">Subdocuments</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/queries.html">Queries</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/validation.html">Validation</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/middleware.html">Middleware</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/populate.html">Populate</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/discriminators.html">Discriminators</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/plugins.html">Plugins</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/api.html">API</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/mongoose.html">Mongoose</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/schema.html">Schema</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/connection.html">Connection</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/document.html">Document</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/model.html">Model</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/query.html">Query</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/aggregate.html">Aggregate</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/schematype.html">SchemaType</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/virtualtype.html">VirtualType</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/compatibility.html">Version Compatibility</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/faq.html">FAQ</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/further_reading.html">Further Reading</a></li></ul><div class="cpc-ad"><script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=mongoosejscom" id="_carbonads_js"></script></div></div></div><div class="container"><div id="content"><h1 id="working-with-dates">Working With Dates</h1>
<script>
_native.init("CK7DT53U",{
targetClass: 'native-inline'
});
</script>
<div class="native-inline">
<a href="#native_link#"><span class="sponsor">Sponsor</span> #native_company# — #native_desc#</a>
</div>
<p>Here's how you declare a path of type <code>Date</code> with a Mongoose schema:</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);
<span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema({
name: <span class="hljs-built_in">String</span>,
<span class="hljs-comment">// `lastActiveAt` is a date</span>
lastActiveAt: <span class="hljs-built_in">Date</span>
});
<span class="hljs-keyword">const</span> User = mongoose.model(<span class="hljs-string">'User'</span>, userSchema);</code></pre>
<p>When you create a user <a href="/docs/documents.html">document</a>, Mongoose will cast
the value to a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">native JavaScript date</a>
using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Syntax"><code>Date()</code> constructor</a>.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User({
name: <span class="hljs-string">'Jean-Luc Picard'</span>,
lastActiveAt: <span class="hljs-string">'2002-12-09'</span>
});
user.lastActiveAt <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Date</span>; <span class="hljs-comment">// true</span></code></pre>
<p>An invalid date will lead to a <code>CastError</code> when you <a href="/docs/validation.html">validate the document</a>.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User({
name: <span class="hljs-string">'Jean-Luc Picard'</span>,
lastActiveAt: <span class="hljs-string">'not a date'</span>
});
user.lastActiveAt <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Date</span>; <span class="hljs-comment">// false</span>
user.validateSync().errors[<span class="hljs-string">'lastActiveAt'</span>]; <span class="hljs-comment">// CastError</span></code></pre>
<h2 id="validators">Validators</h2>
<p>Dates have two built-in validators: <code>min</code> and <code>max</code>. These validators will
report a <code>ValidatorError</code> if the given date is strictly less than <code>min</code> or
strictly greater than <code>max</code>.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> episodeSchema = <span class="hljs-keyword">new</span> mongoose.Schema({
title: <span class="hljs-built_in">String</span>,
airedAt: {
type: <span class="hljs-built_in">Date</span>,
<span class="hljs-comment">// The dates of the first and last episodes of</span>
<span class="hljs-comment">// Star Trek: The Next Generation</span>
min: <span class="hljs-string">'1987-09-28'</span>,
max: <span class="hljs-string">'1994-05-23'</span>
}
});
<span class="hljs-keyword">const</span> Episode = mongoose.model(<span class="hljs-string">'Episode'</span>, episodeSchema);
<span class="hljs-keyword">const</span> ok = <span class="hljs-keyword">new</span> Episode({
title: <span class="hljs-string">'Encounter at Farpoint'</span>,
airedAt: <span class="hljs-string">'1987-09-28'</span>
});
ok.validateSync(); <span class="hljs-comment">// No error</span>
<span class="hljs-keyword">const</span> bad = <span class="hljs-keyword">new</span> Episode({
title: <span class="hljs-string">'What You Leave Behind'</span>,
airedAt: <span class="hljs-string">'1999-06-02'</span>
});
bad.airedAt; <span class="hljs-comment">// "1999-06-02T00:00:00.000Z"</span>
<span class="hljs-comment">// Path `airedAt` (Tue Jun 01 1999 20:00:00 GMT-0400 (EDT)) is after</span>
<span class="hljs-comment">// maximum allowed value (Sun May 22 1994 20:00:00 GMT-0400 (EDT)).</span>
bad.validateSync();</code></pre>
<h2 id="querying">Querying</h2>
<p>MongoDB supports querying by date ranges and sorting by dates. Here's some
examples of querying by dates, date ranges, and sorting by date:</p>
<pre><code class="language-javascript"><span class="hljs-comment">// Find episodes that aired on this exact date</span>
<span class="hljs-keyword">return</span> Episode.find({ airedAt: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'1987-10-26'</span>) }).
then(episodes => {
episodes[<span class="hljs-number">0</span>].title; <span class="hljs-comment">// "Where No One Has Gone Before"</span>
<span class="hljs-comment">// Find episodes within a range of dates, sorted by date ascending</span>
<span class="hljs-keyword">return</span> Episode.
find({ airedAt: { $gte: <span class="hljs-string">'1987-10-19'</span>, $lte: <span class="hljs-string">'1987-10-26'</span> } }).
sort({ airedAt: <span class="hljs-number">1</span> });
}).
then(episodes => {
episodes[<span class="hljs-number">0</span>].title; <span class="hljs-comment">// "The Last Outpost"</span>
episodes[<span class="hljs-number">1</span>].title; <span class="hljs-comment">// "Where No One Has Gone Before"</span>
});</code></pre>
<h2 id="casting-edge-cases">Casting Edge Cases</h2>
<p>Date casting has a couple small cases where it differs from JavaScript's
native date parsing. First, Mongoose looks for a <a href="https://www.w3schools.com/jsref/jsref_valueof_string.asp"><code>valueOf()</code> function</a> on the given object,
and calls <code>valueOf()</code> before casting the date. This means Mongoose can cast
<a href="http://npmjs.com/package/moment">moment objects</a> to dates automatically.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> moment = <span class="hljs-built_in">require</span>(<span class="hljs-string">'moment'</span>);
<span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User({
name: <span class="hljs-string">'Jean-Luc Picard'</span>,
lastActiveAt: moment.utc(<span class="hljs-string">'2002-12-09'</span>)
});
user.lastActiveAt; <span class="hljs-comment">// "2002-12-09T00:00:00.000Z"</span></code></pre>
<p>By default, if you pass a numeric
string to the Date constructor, JavaScript will attempt to convert it to a
year.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">1552261496289</span>); <span class="hljs-comment">// "2019-03-10T23:44:56.289Z"</span>
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'1552261496289'</span>); <span class="hljs-comment">// "Invalid Date"</span>
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'2010'</span>); <span class="hljs-comment">// 2010-01-01T00:00:00.000Z</span></code></pre>
<p>Mongoose converts numeric strings that contain numbers outside the <a href="https://stackoverflow.com/questions/11526504/minimum-and-maximum-date">range of representable dates in JavaScript</a> and converts them to numbers before passing them to the date constructor.</p>
<pre><code class="language-javascript"><span class="hljs-built_in">require</span>: <span class="hljs-built_in">Date</span> Tutorial.*Example <span class="hljs-number">1.4</span><span class="hljs-number">.3</span>]</code></pre>
<h2 id="timezones">Timezones</h2>
<p><a href="http://bsonspec.org/spec.html">MongoDB stores dates as 64-bit integers</a>, which
means that Mongoose does <strong>not</strong> store timezone information by default. When
you call <code>Date#toString()</code>, the JavaScript runtime will use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset">your OS' timezone</a>.</p>
</div></div><script type="text/javascript">var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://g0a3nbw0xa.execute-api.us-east-1.amazonaws.com/prod/track', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {};
xhr.send(JSON.stringify({
path: window.location.pathname,
hostname: window.location.hostname,
hash: window.location.hash
}));</script><script type="text/javascript" src="/docs/js/navbar-search.js"></script><script type="text/javascript">(function (window, document) {
var layout = document.getElementById('layout'),
menu = document.getElementById('menu'),
menuLink = document.getElementById('menuLink'),
content = document.getElementById('content');
function toggleClass(element, className) {
var classes = element.className.split(/\s+/),
length = classes.length,
i = 0;
for(; i < length; i++) {
if (classes[i] === className) {
classes.splice(i, 1);
break;
}
}
// The className is not found
if (length === classes.length) {
classes.push(className);
}
element.className = classes.join(' ');
}
function toggleAll(e) {
var active = 'active';
e.preventDefault();
toggleClass(layout, active);
toggleClass(menu, active);
toggleClass(menuLink, active);
}
menuLink.onclick = function (e) {
toggleAll(e);
};
content.onclick = function(e) {
if (menu.className.indexOf('active') !== -1) {
toggleAll(e);
}
};
}(this, this.document));</script></div></body></html>