我想知道Oracle是否能够将日期与不同的时区进行比较,如:
12/26/2016 3:58:16.491476 AM -06:00> 12/26/2016 3:58:16.491476 AM +05:00
顺便说一下,我使用JPA进行比较,我的想法是查找一小时前创建的所有行。
我发现我可以使用After关键字来查找它(即findMeasureDateAfter)
答案 0 :(得分:1)
很容易在Oracle中检查。答案是肯定的。请注意,在下图中,输出显示使用我的会话的NLS设置的时间戳(我并不关心更改它们)。
var express = require("express");
var router = express.Router();
var flash = require("connect-flash");
var fs = require('fs');
var firebase = require("firebase");
var gcloud = require('google-cloud');
var multer = require("multer");
var upload = multer({dest:"./public/images/uploads/", limits: {fileSize: 250000}}).single("image");
// Enable Storage
var gcs = gcloud.storage({
projectId: 'grape-spaceship-123',
keyFilename: '/path/to/keyfile.json'
});
// Reference an existing bucket.
var bucket = gcs.bucket('my-existing-bucket');
router.get("/", function(req, res, next){
if (firebase.auth().currentUser == null) {
global.page_name = "login";
res.render("users/login");
}
else {
global.page_name = "upload";
res.render("upload");
}
});
router.post("/", function(req, res, next){
upload(req,res, function (err) {
if (err) {
req.flash("error_msg", "File too large. Max Size: 250KB");
res.redirect("/upload");
return
}
var title = req.body.title;
var section = req.body.section;
// Validation
req.checkBody('title', 'Title is required').notEmpty();
req.checkBody('title', 'Title is too long, max: 50 charachters !').len(0,50);
req.checkBody('section', 'Section is required').notEmpty();
var errors = req.validationErrors();
if(errors){
res.render('upload', {
errors: errors
});
}
else {
if (req.file){
console.log("image saved successfully in local");
//upload to the GCloud
bucket.upload(req.file.filename, function(err, file) {
if (!err) {
console.log("image saved successfully in GCloud");
//remove local image
fs.unlink(req.file.filename, (err) => {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
//store image name in firebase
var image = file.name;//may be another key hold the image name.
var section = req.body.section.toLowerCase();
var IDref = firebase.database().ref("posts/"+section+"/lastID");
IDref.once("value", function(IDsnapshot){
var number = IDsnapshot.val();
var postRef = firebase.database().ref("posts/"+section).push();
var UID = postRef.key;
var post = {
title: req.body.title,
section: req.body.section,
image: image,
author: firebase.auth().currentUser.uid,
section: section,
upvotes: 0,
downvotes: 0,
id: number + 1,
key: UID
}
IDref.set(post.id);
postRef.set(post);
var authoredPost = {
title: req.body.title,
section: section,
}
var userRef = firebase.database().ref("users/"+firebase.auth().currentUser.uid.toString()+"/posts/"+UID.toString());
userRef.set(authoredPost);
});
req.flash("success_msg", "Post Created");
res.redirect("/upload");
}
});
}
else {
console.log("No file uploaded");
req.flash("error_msg", "Image is required");
res.redirect("/upload");
}
}
});
});
module.exports = router;
如果你是基于这样的谓词从Oracle表中提取数据,那么在数据库中完成这项工作要好得多 - 所以如何在Java中完成这项工作是无关紧要的。 (你肯定不想获取所有的行,只是在用Java检查时间戳后忽略大部分行。)当然,如果你需要"最后一小时"你会与with
inputs ( ts1, ts2 ) as (
select to_timestamp_tz('12/26/2016 3:58:16.491476 AM -06:00',
'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM'),
to_timestamp_tz('12/26/2016 3:58:16.491476 AM +05:00',
'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM') from dual
)
select ts1, ts2, case when ts1 > ts2 then 'ts1 > ts2'
when ts1 = ts2 then 'ts1 = ts2'
when ts1 < ts2 then 'ts1 < ts2'
end as comparison,
ts1 - ts2 as difference
from inputs
;
TS1 TS2 COMPARISON DIFFERENCE
----------------------------- ----------------------------- ---------- -------------------
26-DEC-16 03.58.16.491 AM -06 26-DEC-16 03.58.16.491 AM +05 ts1 > ts2 +00 11:00:00.000000
进行比较。
答案 1 :(得分:0)
首先,如果这些输入实际上是问题中提供的字符串,则尽可能使用标准ISO 8601格式。标准格式对人类来说很直观,而且计算机更容易解析。实际上,java.time类在解析/生成字符串时默认使用ISO 8601格式。
虽然我不知道Oracle中的查询(我自己就是Postgres的人),但我可以展示如何在Java端更多地形成查询。
理想情况下,我们会将输入字符串解析为OffsetDateTime
,因为它缺少时区指示,只有从UTC偏移。区域是偏移加上一组用于处理夏令时(DST)等异常的规则。时区的格式为continent/region
,例如America/Montreal
。
不幸的是,Java 8中的java.time实现在解析DateTimeFormatter
类中的UTC偏移时存在一些缺陷。所以在Java 9之前,这里有一些hack代码要解析为ZonedDateTime
并转换为更合适的OffsetDateTime
。
String input = "12/26/2016 3:58:16.491476 AM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "MM/dd/uuuu h:m:s.SSSSSS a z" , Locale.ENGLISH );
OffsetDateTime odt = ZonedDateTime.parse ( input , f ).toOffsetDateTime ();
odt.toString():2016-12-26T03:58:16.491476-06:00
重复你的结束时刻。
如果JDBC驱动程序支持JDBC 4.2或更高版本,则可以通过PreparedStatement::setObject
直接传递这些java.time类型。
如果没有,请转换为java.sql类型。要转换,请查看添加到旧类的新方法。 from
方法采用Instant
,这是UTC时间轴上的一个时刻。您可以将Instant
视为剥离其偏移的OffsetDateTime
。致电OffsetDateTime::toInstant
以提取Instant
。
java.sql.Timestamp ts = java.sql.Timestamp.from( odt.toInstant() ) ;
为您的开始和结束时刻执行此操作。将这些java.sql.Timestamp
个对象传递给您的PreparedStatement
。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。