将带有美国日期和时间格式的字符串转换为英国格式

时间:2011-09-20 20:13:12

标签: sql sql-server tsql sql-server-2008

我有一个应用程序,它将日期和时间存储在SQL Server 2008表的字符串字段中。

应用程序根据正在运行的PC的区域设置存储日期和时间,我们无法更改此行为。

问题是有些PC必须采用12小时的英国日期格式(例如22/10/2011 1:22:35 pm),其中一些英国日期格式为24小时(例如22/10/2011) 13:22:25)有些必须是美国日期格式(例如10/22/2011 1:22:35 pm)和(例如10/22/2011 13:22:25)。

是否有任何自动方式在每次更改/添加到表格时更改字符串为UK 24h格式,因此数据库中的格式始终相同?

可以使用更新或插入时的某些触发器来完成吗?是否有任何内置函数已经这样做了?

即使是不时运行它的脚本也可以完成这项工作...... 我想将字符串拆分为日,月,年,小时,分钟,秒,上午/下午,然后将日期和月份部分放入dd/mm顺序,并以某种方式将小时部分更改为24小时,如果PM ,摆脱“上午”和“下午”,然后将修改后的日期/时间放回到表格中。

例如表格

id datestring              value           Location   
1  15/10/2011 11:55:01 pm  BLAHBLAH        UK
2  15/10/2011 13:12:20     BLAKBLAK        GR
3  10/15/2011 6:00:01 pm   SOMESTUFF       US
4  10/15/2011 20:16:43     SOMEOTHERSTUFF  US

我们希望它是

id datestring           value              Location
1  15/10/2011 23:55:01  BLAHBLAH           UK
2  15/10/2011 13:12:20  BLAKBLAK           GR
3  15/10/2011 18:00:01  SOMESTUFF          US
4  15/10/2011 20:16:43  SOMEOTHERSTUFF     US

我们可以使用datepart函数正确显示日期部分(日,月,年),但是时间部分我们遇到问题,因为它改变了太多方法。

编辑解释更多

先生。 p.campbell感谢编辑..我不知道如何美化它:))

和先生。马修,谢谢你的快速回复..

我们可以判断它是英国日期还是美国日期,因为根据PLC机器的位置我们有另一个字段我没有提及“US”,“UK”,“GR”,“IT”文本。

对不起,我没有解释清楚。我的英语不太好。

有两种不同且独立的应用程序。并且它们与sql server没有直接关系。

只将数据写入数据库的应用程序.lets将其称为“作者”简称..以及另一个读取数据的应用程序..让它称之为“读者”。

“编写器”是PLC机器的内部应用程序,它每1分钟将值存储到数据库中,这就是我们无法改变其行为的原因。它使用字符串数据类型根据守护程序应用程序运行的pc的区域设置在同一字段中存储日期和时间,并在PC和PLC机器之间进行通信。

现在“读者”希望日期和时间的格式为“dd / mm / yyyy 23:23:01”或“yyyy / mm / dd 23:23:01”,它唯一能做的就是现在正在使用给定日期之间的值字段中的数据进行一些计算。例如。从10/09/2011 10:00:00到15/09/2011 14:00:00。

我们只需要做这样的事情......

从table1中选择*,其中“10/09/2011 10:00:00”和“15/09/2011 14:00:00”之间的日期字符串

我可以发布一些代码,但会发帖很长。

2 个答案:

答案 0 :(得分:4)

起初,我同意马修,但后来我意识到,根据所提供的信息,这实际上 可能(好吧,sorta)。

然而,一些警告;

  1. 通过这种方式存储和维护数据库,您无需任何任何优惠。最好的办法是更改应用程序,使其具有实际的Datetime值,而不是这个错误的字符串。
  2. 此数据 CAN NOT 按日期或时间进行有意义的排序(不是没有执行昂贵的字符串操作)。
  3. 您似乎将所有时间都存储为本地次,但似乎不会存储TimeZone或相关信息。如果没有这些信息,您将 NOT 能够(完全)正确地“全球”翻译时间。例如,晚些时候 - 伦敦时间下午4点,纽约上午11点(例如国际电话会议)?答案是你不知道:这取决于一年中的时间。
  4. 您正在存储当地时间,期间。只有本地时间正确才能使用。当有人将时钟设置为1900时会发生什么?您应该根据 SERVER'S 时钟存储时间。
  5. 您存储的时间戳基于格式化字符串。如果用户更改其时间显示方式,则数据正确性(可能)会超出窗口。例如,如果有人移除上午/下午的符号,会想“我会看着窗外 - 如果太阳出来了,那就是'我'?”
  6. 请记住所有这些。


    关于如何做到这一点....
    我不打算为此写出SQL语句。主要是因为以这种方式存储信息非常糟糕。但也因为它需要做很多工作而我不愿意做。我确实建议强调任何人都有你的位置的密钥来更改该应用程序。

    相反,我会给你一个非常大的线索 - 这只会在你的时间戳格式保持不变的情况下起作用;你能够根据字符串中是否存在'am'和'pm'来判断日期和时间的格式(如果你没有,那么你就是平坦的吐司)。正如Matthew指出的那样,日期的格式也可能不同,以及时间 - 您需要翻译两者。但是,由于比较时间戳,这将立即给您带来问题(请参见上面的第4点);任何使用这个数据运行调度或审计的尝试都注定要失败(“这是什么时候发生的?”“嗯,这是英国的日期格式,所以......”“但这使得它在这里1AM,他是那么死了!“)。

    最有益的答案:更改信息在数据库中的存储方式


    修改

    然后它打击了我(特别是根据新的编辑) - 可能还有其他可能使这项工作成为可能......

    首先,根据服务器的时钟,将数据库更改为实际存储某种“全球化”时间戳。
    这当然会破坏您现有的应用程序代码 - 它会产生数据类型不匹配错误。要解决此问题,请重命名该表,然后创建一个名称与原始表相同的视图,该视图将返回格式化为“source”列中指示的字符串。您需要为视图创建instead-of触发器,以将格式化的字符串转换为实际的datetime值。最好的部分是,应用程序代码永远不会注意到差异。您似乎已经表明您对数据库有足够的控制权以允许这种情况发生;这应该允许您透明地“修复”数据。

    如果传入的日期时间值是绝对的(非本地),这当然最有效。希望这些值实际上应该是“插入时间” - 这些可能会被安全地忽略,支持使用特殊寄存器(如NOWCURRENT DATE或其他)。

    不敢相信这不会让我早点出现......

答案 1 :(得分:2)

您说您无法更改应用程序行为,因此这是不可能的

您的问题是您的数据库不知道客户端的文化/时区设置,而您的客户端也没有报告。

您需要报告此数据或想出明智的方法来推断此信息,然后才能采取行动。

编辑:例如,如果不了解客户的详细信息,您如何辨别字符串之间的区别:
10/1/2011 12:00:00(10月1日,中午,美国)
10/1/2011 12:00:00(1月10日,中午,英国)