转换日期时间格式

6

我遇到了一个问题,需要将给定输入格式的日期转换为目标格式。在C#中有没有标准的方法可以做到这一点?

举个例子,假设我们有 yyyy.MM.dd 作为源格式,目标格式是 MM/dd/yyy(当前文化)。

问题出现在,我使用的解析策略优先考虑当前文化,如果失败则尝试从已知格式列表中解析。现在假设我们有两个等价的日期,一个在上述源文化中 (2015.12.9),另一个在当前文化中 (9/12/2015)。如果我们尝试解析这两个日期,则第一种情况下月份将为12,在第二种情况下将为9,因此我们有不一致性(它们应该表示完全相同的日期)。

我认为如果存在,应该是类似于:

DateTime.Convert(2015.12.9, 'yyyy/MM/dd', CultureInfo.CurrentCulture). 

任何想法?
编辑:
感谢大家的想法和建议,但你们大多数人对我的问题的解释并不完全正确。你们大多数人所回答的是在给定格式中进行直接解析,然后转换为当前文化。
DateTime.ParseExact("2015.12.9", "yyyy.MM.dd", CultureInfo.CurrentCulture)

虽然日期是按照当前文化格式显示,但月份仍将返回12。我的问题是,是否有一种标准的方法可以将日期从“yyyy.MM.d”转换为“MM/dd/yyy”格式,以便月份位于正确的位置,然后在目标文化中解析它。这样的函数可能不存在。


或者,Datetime.TryParse 可以使用格式信息(请参见链接页面上的示例)。 - Nathan Cooper
1
如果当前文化是yyyy-mm-dd,而传入的日期是09/12/2015,你会怎么做?你无法知道传入的日期是mm/dd/yyyy还是dd/mm/yyyy。 - Matthew Watson
没错。我放弃了这个问题。这是我的主管提出的要求,但我已经说服他这是不可能的,我们唯一能克服这个问题的方法就是检测数据中给定日期时间所使用的格式,然后重新启动解析并强制使用该格式,直到找到一个正确解析所有数据的格式。 - user3853059
你的第一句话应该更具体,因为“在任何格式中”是一个非常普遍的问题,正如Matthew Watson指出的那样,这里会遇到逻辑上的不一致,例如dd/mm和mm/dd,所以几乎是不可能的。你的第二句话表明你有一个单一的输入格式,如所示。你能将问题缩小到特定的输入格式吗? - JPK
@JPK,我的编辑是否澄清了这个问题? - user3853059
@user3853059,为你的努力和对工作的兴趣点赞!你把一个“糟糕”的问题变成了一个更好的问题,现在它是非常可回答的,并且一般来说表明你想要将一个特定的输入格式转换成另一个。 - JPK
3个回答

8

DateTime.ParseExact 是你要找的方法:

DateTime parsedDate = DateTime.ParseExact("2015.12.9", "yyyy.MM.d", CultureInfo.InvariantCulture);

如果您对输入字符串不太自信,可以使用DateTime.TryParseExact


您可以在此处查看所有可用的格式:https://msdn.microsoft.com/library/8kb3ddd4(v=vs.110).aspx - Perfect28

1

我知道现在有点晚了,但如果你让我解释一下,我会尽力让它更深入。

我遇到了一个问题,需要将任何格式的日期转换为目标格式。

不存在所谓的 任何格式的日期。一个 DateTime 没有 任何 隐式格式。它只有日期和时间值。看起来你有一个被格式化成日期的 string,并且你想将另一个 string 转换为 不同的 格式。

在 C# 中有没有标准的方法可以做到这一点?

有的。你可以使用 DateTime.ParseExactDateTime.TryParseExact 先将你的 string 解析为特定格式的 DateTime,然后使用不同的格式生成它的 string 表示。

作为一个例子,假设我们有yyyy.MM.dd作为源格式,目标格式是MM/dd/yyyy(当前文化)。我不理解这句话中“当前文化”的意思,我认为你想要的是yyyy而不是yyy,但你可以按照我上面描述的方式生成它。请注意,保留HTML标签。
string source = "2015.12.9";
DateTime dt = DateTime.ParseExact(source, "yyyy.MM.d", CultureInfo.InvariantCulture);
string target = dt.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture); // 12/09/201

问题出在我使用了一种解析策略,该策略优先考虑当前文化,如果失败则尝试从已知格式列表中解析。
由于您没有展示任何解析策略,并且.NET Framework中没有DateTime.Convert方法,因此我无法进行任何评论。
现在假设我们有两个等效的日期,一个在上述源文化中(2015.12.9),另一个在当前文化中(9/12/2015)。然后,如果我们尝试解析这两个日期,第一个月份将是12,而第二个月份将是9,所以我们有一个不一致性。
再次强调,您没有DateTime。您有字符串。这些格式化字符串不能属于任何文化。当然,所有文化可能会使用相同的格式解析或生成不同的字符串表示形式,但格式并不属于任何文化。
我假设你有两个不同格式的字符串,想要解析输入无论它来自哪一个。在这种情况下,你可以使用DateTime.TryParseExact overload,它将所有可能的格式作为参数传递给字符串数组。然后使用MM/dd/yyy格式和具有/作为DateSeparator的区域设置(例如InvariantCulture)生成它的字符串表示形式。
string s = "2015.12.9"; // or 9/12/2015
string[] formats = { "yyyy.MM.d", "d/MM/yyyy" };
DateTime dt;
if (DateTime.TryParseExact(s, formats, CultureInfo.InvariantCulture,
                           DateTimeStyles.None, out dt))
{
    Console.WriteLine(dt.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture));
}

抱歉我没有表达清楚,这些日期是字符串,但它们可以是任何格式,这是未知的;它是在当前文化解析失败时检测到的。也就是说,我使用DateTime.TryParse(s, formats, CultureInfo.CurrentCulture, out datetimevalue)进行尝试,如果失败了,我会使用DateTime.TryParseExact(str, dateFmts, culture, out datetimevalue)。 - user3853059
@user3853059 很抱歉,您无法使用单个方法解析每个可能格式化的字符串。 您必须知道您所拥有的格式字符串,以便可以成功解析它。 如果您从某个地方获得此作为输入,则最好在 UI 端使用一些验证。 除此之外,据我所知是不可能的。 - Soner Gönül
@Downvoter,能否至少评论一下,让我知道哪里可能出了错? - Soner Gönül

0
最简单和最好的方法是使用.ToString()方法
看看这段代码:
DateTime x =DateTime.Now;  

将它转换只需像这样编写:

x.ToString("yyyyMMdd")//20151210
x.ToString("yyyy/MM/dd)//2015/12/10
x.ToString("yyyy/MMM/dd)//2015/DEC/10  //Careful About M type should be capital for month .  

希望有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接