经典ASP - 服务器时间与本地时间

时间:2012-03-31 16:10:11

标签: sql asp-classic

我有一个经典的ASP应用程序,我正在处理日期切断。我的服务器位于中部时间,但我在东部时间。我的应用程序认为这是一个小时前发生的事情,我的截止时间晚了一个小时。如果用户在太平洋时间,我相信他们会早2小时。

我想弄清楚的是,是否有办法

  1. 告诉服务器显示您在SQL上执行GetDate()或在ASP中执行Now()时的本地时间
  2. 找出一些方法来做一个偏移,我可以在页面首次加载并根据需要使用时运行。
  3. 我尝试了服务器端javascript,它也返回中央时间。任何帮助将不胜感激!!提前谢谢!

    丹尼斯


    更新 - 4/11/12 @ 1:12 pm:


    我认为我找到了一个适用于我的应用程序的工作,但它通常不会起作用。我有我正在使用的位置的地理数据 - 邮政编码。我可以从中获取时区 - 它不能完全适用于查看该位置的其他时区的用户,但这对我的应用程序无关紧要,因为我只需要关注该位置的结束时间。

    这是我发现的其他方式由JohnB提供(特别是#4)。感谢大家。 http://www.webmasterworld.com/forum47/600.htm(下)


6 个答案:

答案 0 :(得分:3)

修改

  

我尝试过服务器端javascript,它也返回中央时间。

您是不是想说客户端 JavaScript?您肯定需要使用客户端脚本来获取用户的设备时间(而不是服务器端脚本)。


您应该阅读:

处理多个时区的入门手册:

1)确保您的数据库服务器在其时区中设置为正确的日期/时间。正确考虑其位置的夏令时。将服务器设置为自动执行此操作。

2)在数据库中创建一个表,其中包含时区及其与UTC(GMT)的偏移量。

3)始终以UTC格式存储Now()日期/时间。每个数据库供应商都应具有UTC日期/时间Now()功能(即SQL Server的SYSUTCDATETIME())。这种方式所有时间都以通用格式存储,与用户恰好坐在的位置无关。 从您的数据库而不是客户端调用Now(),因为移动设备可能位于任何地方,但您的数据库服务器停留在一个位置。

4)让用户输入他们的本地时区并将其存储在您的数据库中。

5)当以UTC格式显示日期/时间返回给用户时,使用用户的时区偏移将UTC日期/时间转换回用户的时区。 SQL Server使datetimeoffset更容易实现。

6)如果用户正在设置闹钟,请让他们在当地时区输入触发日期/时间。这样,用户可以在移动时更改其本地时区。此外,如果时区规则更改,您只需修复时区表(#2),然后警报仍将正确触发。在您的代码中,要测试警报触发器,将触发时间转换为UTC,然后与UTC中的服务器时间进行比较(即SYSUTCDATETIME())。

7)夏令时非常棘手! (见第1个链接)

答案 1 :(得分:2)

通常,时区操作无法在传统ASP中直接完成

但是,如果您完全控制运行代码的服务器,则可以安装以 支持时区的语言编写的COM组件,然后使用经典代码中的该组件ASP环境。

例如,您可以使用C#编写以下组件:

using System;
using System.Runtime.InteropServices;

namespace TimeZoneInfoCom
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [Guid("E0C70A94-352D-4C0B-8C2E-8066C88565C5")]
    public class TimeZoneConverter
    {
        public DateTime NowInZone(string timeZoneId)
        {
            return TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, timeZoneId);
        }

        public DateTime Convert(DateTime dateTime, string sourceZoneId, string targetZoneId)
        {
            TimeZoneInfo sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(sourceZoneId);
            TimeZoneInfo targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById(targetZoneId);
            return TimeZoneInfo.ConvertTime(dateTime, sourceTimeZone, targetTimeZone);
        }
    }
}

然后编译它,将DLL复制到服务器,并将其注册为COM组件(使用RegAsm.exe)。

然后你可以在你的经典ASP页面中调用它,如下所示:

<html>
<body>

Server Time: <%= Now() %><br>
<br>

<% 
Dim tzconverter
Set tzconverter = Server.CreateObject("TimeZoneInfoCom.TimeZoneConverter")
%>

US Pacific Time:  <%= tzconverter.NowInZone("Pacific Standard Time") %><br>
US Mountain Time:  <%= tzconverter.NowInZone("Mountain Standard Time") %><br>
US Central Time:  <%= tzconverter.NowInZone("Central Standard Time") %><br>
US Eastern Time:  <%= tzconverter.NowInZone("Eastern Standard Time") %><br>
UTC:  <%= tzconverter.NowInZone("UTC") %><br>

<br>

Conversion Example:
<%

Dim originalTime, convertedTime
originalTime = #12/31/2014 00:00:00#
convertedTime = tzconverter.Convert(originalTime, "UTC", "Tokyo Standard Time")
Response.Write(convertedTime)

%>

<%
' Don't forget to destroy the com object!
Set tzconverter = Nothing
%>

</body>
</html>

如果你得到一个&#34; ActiveX组件不能创建对象&#34;错误,请确保您已设置&#34;启用32位应用程序&#34;在IIS中的True下,在应用程序池的高级设置下。

关于SQL Server - 如果你搜索,你可能会发现一些帖子显示你可以在SQL Server中操作时间的方法,通过精心设计的存储过程,它们有固定的偏移量,固定的时区规则,或者依赖于时区数据。我通常建议不要采用任何这些方法,因为它们太脆弱了。

  • 固定偏移是不好的,因为它们不会考虑夏令时。
  • 固定规则很糟糕,因为时区规则可以(并且确实)发生变化。编辑存储过程以跟上这些变化太脆弱了(恕我直言)。
  • 维护时区数据表是一个更好,但通常我发现这些表不能很好地维护。如果你沿着这条路走下去,一定要制定一个程序来定期更新表格。

答案 2 :(得分:0)

获取用户时区

http://www.pageloom.com/automatic-timezone-detection-with-javascript

根据我对此JavaScript代码的理解,它非常准确,并且能够从UST返回偏移量,相应的Olson数据库时区名称,并处理夏令时问题(例如-5:00,America / New_york,true)。

在html页面上运行此代码之后,您将面临的唯一障碍可能是将这些值传递给asp,然后再获取sql,如果这是您需要的。我通过使用JQuery将这些值作为$ .post发送来实现这一点。我认为这是最简单的方法。我相信其他选择使用AJAX命令或cookie。

在我从JavaScript代码到服务器的值之后,我将它们存储为会话变量,这样如果我站点上的用户从通常的不同时区登录,它们就会改变。但是,它们也可以很容易地保存到数据库中。

//replace this comment with the most updated timezonedetect code from that first link
var timezone = jstz.determine_timezone();
var tzoffset = timezone.offset();
var tzname = timezone.name();
var tzdst = timezone.dst();
$.post("tzdetect.asp", { tzoffset: tzoffset, tzname: tzname, tzdst: tzdst } );

然后,您需要在服务器上设置接收文件tzdetect.asp,以便在发送时存储时区。

获得时区后使用时区

本文为您的问题提供了一个很好的解决方案:http://www.codeproject.com/Articles/31146/SQL-2005-Time-Zone-Conversion-Functions

  

方法是设置一个名为的标量函数   NEW_TIME采用三个参数:

  • 转换日期
  • 原始时区价值
  • 转换时区
  

并且函数返回   转换价值。

答案 3 :(得分:0)

针对旧问题的新解决方案...

使用我们所有的asp经典应用程序将服务器从“东部标准时间”移动到“ utc”时,我们遇到了这个问题。
但是,我们正在使用SQL Server2017。

并且,如果您使用的是SQL Server 2016+,则可以使用new "at time zone"关键字。

从该查询获取当前的“偏移”:

select datediff(hour, GETUTCDATE() at time zone 'eastern standard time', GETUTCDATE()) as offset

然后,使用该偏移量通过以下功能处理ASP代码中的所有日期:

function fromUTC(dt)
    fromUTC = dateadd("h", tzOFFSET, dt)
end function

function toUTC(dt)
    toUTC = dateadd("h", -1 * tzOFFSET, dt)
end function

function getNow
    getNow = fromUTC(now)
end function

您可以在代码中将所有“现在”替换为“ getNow”。

警告:此偏移量已根据当前日期进行了固定。如果需要处理不同白天的日期,则可以直接在SQL查询中使用“在时区”语法,例如:

DECLARE @timezone NVARCHAR(100) = N'eastern standard time'
SELECT 
    u.name, 
    u.last_visit   at time zone @timezone as last_visit_tz,
    u.date_created at time zone @timezone as date_created_tz
FROM users u

答案 4 :(得分:0)

您可以检查例如网站http://worldclockapi.com。您可以将当前时间作为时区。

示例:在http://worldclockapi.com/api/json/est/now。 您可以看到EST的当前日期,时间和其他数据。

示例:在http://worldclockapi.com/api/json/pst/now上,您可以看到PST当前日期,时间和其他数据...

您可以使用XMLHTTP从外部站点获取数据。

private Function GETHTTP(adres)
     Set StrHTTP = Server.CreateObject("Microsoft.XMLHTTP" )
     StrHTTP.Open "GET" , adres, false
     StrHTTP.sEnd
     GETHTTP = StrHTTP.Responsetext
     Set StrHTTP = Nothing
End Function

full_data= GETHTTP("http://worldclockapi.com/api/json/est/now")

然后,您使用split以逗号分隔:

parts=split(full_data,",")
response.write parts(1)

答案 5 :(得分:-2)

我认为如果你选择下面你需要的那个,然后放在你的页面顶部,它将默认为该位置而不是服务器 - http://msdn.microsoft.com/en-us/library/ms524330(v=vs.90).aspx

' This file does not need @LCID or @CODEPAGE and 
'  it does not need to be saved in UTF-8 format because  
'  there are no literal strings that need formatting or encoding. 

Response.Codepage = 65001 
Response.Charset = "utf-8" 

' See what happens when you uncomment the lines below. 
'Response.Codepage = 1252 
'Response.Charset = "windows-1252" 

ShowDateTimeCurrency 1033, "North America" 
ShowDateTimeCurrency 1041, "Japan" 
ShowDateTimeCurrency 1049, "Russia" 
ShowDateTimeCurrency 1031, "Germany" 
ShowDateTimeCurrency 1025, "Saudi Arabia" 
ShowDateTimeCurrency 1081, "India" 
ShowDateTimeCurrency 2052, "China" 
ShowDateTimeCurrency 1042, "Korea" 

Sub ShowDateTimeCurrency(iLCID, sLocale) 
  Response.LCID = iLCID 
  Response.Write "<B>" & sLocale & "</B><BR>" 
  Response.Write FormatDateTime(Date, 1) & "<BR>" 
  Response.Write FormatDateTime(Time, 3) & "<BR>" 
  Response.Write FormatCurrency(1000) & "<BR>" 
  Response.Write FormatNumber(50, 3, 0, 0, -1) & " & " & FormatNumber(.02, 3, 0, 0, -1) & "<BR><BR>" 
End Sub

看看这里 - http://msdn.microsoft.com/en-us/library/ms524330(v=vs.90).aspx

或其他方式是使用日期addadd函数

如果有帮助,请标记为答案 感谢