在 javascript 中将字符串解析为 Date
Parse string to Date in javascript
我正在创建一个函数来比较自定义日期时间和当前日期时间。在比较之前,我将字符串dd/MM/yyyy HH:mm:ss
转换为new Date()
。
这是代码:
var getCurrentDateTime = function () {
var dt = new Date(),
dd = dt.getDate(),
MM = dt.getMonth() + 1,
yyyy = dt.getFullYear(),
HH = dt.getHours(),
mm = dt.getMinutes(),
ss = dt.getSeconds();
return new Date(yyyy, MM, dd, HH, mm, ss)
};
var parseTimeString = function (d) {
// `d` formatting: 'dd/MM/yyyy HH:mm:ss'
var d_d = d.split(' ')[0],
d_t = d.split(' ')[1],
//x = new Date(2016, 01, 14, 21, 40, 00),
x = new Date(+d_d.split('/')[2], +d_d.split('/')[1] - 1,
+d_d.split('/')[0], +d_t.split(':')[0],
+d_t.split(':')[1], +d_t.split(':')[2]),
c = getCurrentDateTime(),
z = Math.abs((c.getTime() - x.getTime())/1000);
if (z <= 29) {
return 'Just now'
}
if (z > 29 && z < 60) {
return '30 seconds ago'
}
if (z >= 60 && z < 120) {
return '1 minute ago'
}
if (z >= 120 && z < 3600) {
return (c.getMinutes() - x.getMinutes()) + ' minutes ago'
}
if (z >= 3600 && z < 7200) {
return '1 hour ago'
}
if (z >= 7200 && z < 86400) {
return (c.getHours() - x.getHours()) + ' hours ago'
}
if (z >= 86400 && z < 172800) {
var m = x.getMinutes();
return 'Yesterday ' + x.getHours() + ':' + (m < 10 ? '0' + m : m)
}
if (z >= 172800) {
var dd = x.getDate(),
MM = x.getMonth() + 1,
yyyy = x.getFullYear(),
m = x.getMinutes();
dd = dd < 10 ? '0' + dd : dd;
MM = MM < 10 ? '0' + MM : MM;
return dd + '/' + MM + '/' + yyyy + ' at ' + x.getHours() + ':' + (m < 10 ? '0' + m : m)
}
};
$('button').click(function () {
setInterval(function () {
var x = parseTimeString('14/01/2016 21:40:00');
$('body').html($('<p>').text(x))
}, 1000)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me</button>
我的问题:
该行
x = new Date(+d_d.split('/')[2], +d_d.split('/')[1] - 1,
+d_d.split('/')[0], +d_t.split(':')[0],
+d_t.split(':')[1], +d_t.split(':')[2])
未正确转换为new Date()
。当前日期时间为:2016/01/14 21:40:00
,但它打印14/01/2016 at 21:40
而不是Just now
为了再次检查,我已将该行替换为
x = new Date(2016, 01, 14, 21, 40, 00)
而且它运行良好。那么,为什么呢?
p/s:我的子问题:如果我在同一时间内使用超过 20 个间隔,有什么问题吗?(我的网页运行缓慢吗?
首先,正如我在评论中指出的那样,您的getCurrentDateTime()
函数过于复杂,并且在月份字段中还有一个"关闭一个"错误,这可能是您的实际问题的原因:
function getCurrentDateTime() {
return new Date();
}
这个功能现在可以说是如此微不足道,以至于不值得拥有。
其次,您应该将日期的解析与后续位分开,将其转换为人类可读的内容:
function parseDateTime(s) {
var date_time = s.split(' ');
var date = date_time[0];
var time = date_time[1];
var dmy = date.split('/').map(Number);
var hms = time.split(':').map(Number);
return new Date(dmy[2], dmy[1] - 1, dmy[0], hms[0], hms[1], hms[2]);
}
或者如果你喜欢ES6代码高尔夫:
let parseTime=(s)=>new(Function.prototype.bind.apply(Date,
s.match(/^('d'd?)'/('d'd?)'/('d{1,4})'s+('d'd?):('d'd?):('d'd?)$/)
.map((_,i,a)=>a[i<4?4-i:i]-+(i===2))))
然后:
//
// pass an already-parsed `Date` object here
//
function longAgo(t) {
// no need for conversions - subtraction will automatically
// call `.getValue()` to get the milliseconds value
//
// - also no call to 'Math.abs' so that the function works
// correctly for future dates
var z = (Date.now() - t) / 1000;
if (z >= 0 && z < 30) {
// etc
}
}
您的getCurrentDateTime
函数已损坏。我不知道你为什么把它复杂化得如此复杂——它只是Date
的替代品,不是吗?
var getCurrentDateTime = function () {
return new Date();
};
var parseTimeString = function (d) {
var dateRegex = /^([0-9]{1,2})'/([0-9]{1,2})'/([0-9]{4})'s+([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})$/;
var matches = dateRegex.exec(d);
console.log(matches);
if(!matches || matches.length<7)
throw new Error("Invalid date.");
var givenDate = new Date(1*matches[3],
1*matches[2]-1,
1*matches[1],
1*matches[4],
1*matches[5],
1*matches[6]);
var currentDate = getCurrentDateTime();
var difference = Math.abs((currentDate.getTime() - givenDate.getTime())/1000);
if (difference <= 29) {
return 'Just now'
}
if (difference > 29 && difference < 60) {
return '30 seconds ago'
}
if (difference >= 60 && difference < 120) {
return '1 minute ago'
}
if (difference >= 120 && difference < 3600) {
return (currentDate.getMinutes() - x.getMinutes()) + ' minutes ago'
}
if (difference >= 3600 && difference < 7200) {
return '1 hour ago'
}
if (difference >= 7200 && difference < 86400) {
return (currentDate.getHours() - givenDate.getHours()) + ' hours ago'
}
if (difference >= 86400 && difference < 172800) {
var m = givenDate.getMinutes();
return 'Yesterday ' + givenDate.getHours() + ':' + (m < 10 ? '0' + m : m)
}
if (difference >= 172800) {
var dd = givenDate.getDate(),
MM = givenDate.getMonth() + 1,
yyyy = givenDate.getFullYear(),
m = givenDate.getMinutes();
dd = dd < 10 ? '0' + dd : dd;
MM = MM < 10 ? '0' + MM : MM;
return dd + '/' + MM + '/' + yyyy + ' at ' + givenDate.getHours() + ':' + (m < 10 ? '0' + m : m)
}
};
$('button').click(function () {
var starttime = new Date();
var asString = "14/01/2016 "+starttime.getHours()+":"+starttime.getMinutes()+":"+starttime.getSeconds();
setInterval(showDate, 1000, asString);
function showDate(startDate) {
var x = parseTimeString(startDate);
$('body').html($('<p>').text(x))
}
showDate(asString);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me</button>
您的代码存在一些问题。正如其他答案中提到的,getCurrentDate 函数不值得拥有,您不妨只做:
new Date();
解析日期时,您不仅需要验证模式,还需要验证值(例如,25:06:63 的时间无效)。您可以将解析和验证捆绑在一个函数中,以便在值无效时返回一个以 NaN 作为时间值的 Date 对象(这是 ECMA-262 所说的)。
此外,在执行"时间前"部分时,您不需要比较的>=
部分,因为每个if块都会返回(如案例块)。把它放在一起:
/* Parse string in d/m/y h:m:s format to date
** If date string is invalid date, return Date with time value
** of NaN (per ECMA-262)
**
** @param {string} s - date string in format dd/mm/yyyy hh:mm:ss
** @returns {Date}
*/
function parseDMYHMS(s) {
var b = s.split(/'D/);
var d = new Date(b[2], --b[1], b[0], b[3], b[4], b[5]);
// Validate the date string components based on the created Date
return d && d.getMonth() == b[1] && d.getHours() == b[3] && d.getMinutes() == b[4]? d : new Date(NaN);
}
/* Return how long ago d was
**
** @param {Date} d
** @returns {string} or undefined if invalid input
*/
function timeAgo(d) {
if (!d || !d.getTime()) return; // Deal with falsey input, assume Date otherwise
function pad(n){return ('0'+n).slice(-2)}
var z = (new Date() - d) / 1e3; // Time difference in seconds
if (z < 30) return 'Just now';
if (z < 60) return '30 seconds ago';
if (z < 120) return '1 minute ago';
if (z < 3600) return (z/60 | 0) + ' minutes ago';
if (z < 7200) return '1 hour ago';
if (z < 86400) return (z/3600 | 0) + ' hours ago';
if (z < 172800) return 'Yesterday ' + d.getHours() + ':' + pad(d.getMinutes());
return pad(d.getDate()) + '/' + pad(d.getMonth()+1) + '/' + d.getFullYear();
}
function showTimeago(s) {
document.getElementById('div0').innerHTML = timeAgo(parseDMYHMS(s));
}
<label for="in0">Date (d/m/y h:m:s)<input id="in0" onblur="showTimeago(this.value)" value="14/01/2016 10:03:01"></label>
<br>
<div id="div0"></div>
相关文章:
- 新Date()javascript的日期字符串
- JS:如何将字符串(“2015年3月10日”)转换为Date对象
- 确定字符串是Date还是Number
- Javascript Date对象到日期字符串
- 如何从字符串构造一个 javascript Date 对象
- 将字符串转换为 JavaScript 的 Date 对象的方法
- Date() 将某些日期字符串转换为本地时间
- 需要 Date.parse 以外的方法来解析日期字符串
- JavaScript Date 对象不适用于传递给它的字符串
- Date.parse 适用于字符串,但不适用于同一字符串的变量
- pickadate.js-3.5.3 将字符串日期转换为 mysql DATE 的正确格式
- 按数字和字符串设置新的 Date() 会给出不同的结果
- Javascript Date 字符串构造错误的日期
- 验证输入字符串并将其转换为新的 Date 对象
- 在 javascript 中将字符串解析为 Date
- IE 10+无法解析使用自己的date.prototype.toLocaleString生成的日期字符串
- 如何解析具有Date属性的JSON字符串
- 为什么将字符串附加到Date会调用toString()而不是valueOf()
- Javascript new Date(字符串)返回一天后
- 如何判断Date字符串是否包含已在Javascript中添加的时间偏移量