ฉันจะฟอร์แมต DateTime ที่ไม่มีค่าด้วย ToString () ได้อย่างไร


226

ฉันจะแปลง DateTime dt2 ที่ไม่สามารถแปลงเป็นสตริงที่จัดรูปแบบได้อย่างไร?

DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss")); //works

DateTime? dt2 = DateTime.Now;
Console.WriteLine(dt2.ToString("yyyy-MM-dd hh:mm:ss")); //gives following error:

ไม่มีวิธีการมากเกินไป ToString ใช้เวลาหนึ่งอาร์กิวเมนต์


3
สวัสดีคุณคิดจะทบทวนคำตอบที่ยอมรับและเป็นปัจจุบันหรือไม่? คำตอบประจำวันที่เกี่ยวข้องมากขึ้นอาจถูกต้องมากขึ้น
iuliu.net

คำตอบ:


335
Console.WriteLine(dt2 != null ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "n/a"); 

แก้ไข: ตามที่ระบุไว้ในความคิดเห็นอื่นตรวจสอบว่ามีค่าไม่เป็นโมฆะ

อัปเดต: ตามที่แนะนำในความคิดเห็นวิธีการขยาย:

public static string ToString(this DateTime? dt, string format)
    => dt == null ? "n/a" : ((DateTime)dt).ToString(format);

และเริ่มต้นใน C # 6 คุณสามารถใช้โอเปอเรเตอร์ที่มีเงื่อนไขเพื่อทำให้โค้ดง่ายขึ้น การแสดงออกด้านล่างจะกลับเป็นโมฆะถ้าDateTime?เป็นโมฆะ

dt2?.ToString("yyyy-MM-dd hh:mm:ss")

26
ดูเหมือนว่าจะขอทานสำหรับวิธีการขยายให้ฉัน
David Glenn

42
.Value เป็นกุญแจสำคัญ
stuartdotnet

@ David ไม่ว่างานจะไม่สำคัญ ... stackoverflow.com/a/44683673/5043056
Sinjai

3
คุณพร้อมหรือยัง ... dt?. ToString ("dd / MMM / yyyy")? "" ข้อดีที่ยอดเยี่ยมของ C # 6
Tom McDonough

ข้อผิดพลาด CS0029: ไม่สามารถแปลงประเภท 'string' เป็น 'System.DateTime โดยปริยาย?' (CS0029) .Net Core 2.0
Oracular Man

80

ลองใช้ขนาดนี้ดู:

วัตถุ DateTime จริงที่คุณต้องการจัดรูปแบบอยู่ในคุณสมบัติ dt.Value และไม่ได้อยู่ในวัตถุ dt2

DateTime? dt2 = DateTime.Now;
 Console.WriteLine(dt2.HasValue ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "[N/A]");

36

พวกคุณทุกคนอยู่เหนือวิศวกรรมทั้งหมดนี้และทำให้มันซับซ้อนกว่าที่เป็นจริง สิ่งสำคัญหยุดใช้ ToString และเริ่มใช้การจัดรูปแบบสตริงเช่น string รูปแบบหรือวิธีการที่สนับสนุนการจัดรูปแบบสตริงเช่น Console.WriteLine นี่คือทางออกที่ต้องการสำหรับคำถามนี้ นี่คือสิ่งที่ปลอดภัยที่สุด

ปรับปรุง:

ฉันอัปเดตตัวอย่างด้วยวิธีการล่าสุดของคอมไพเลอร์ C # ในปัจจุบัน ตัวดำเนินการตามเงื่อนไข & การแก้ไขสตริง

DateTime? dt1 = DateTime.Now;
DateTime? dt2 = null;

Console.WriteLine("'{0:yyyy-MM-dd hh:mm:ss}'", dt1);
Console.WriteLine("'{0:yyyy-MM-dd hh:mm:ss}'", dt2);
// New C# 6 conditional operators (makes using .ToString safer if you must use it)
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
Console.WriteLine(dt1?.ToString("yyyy-MM-dd hh:mm:ss"));
Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss"));
// New C# 6 string interpolation
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
Console.WriteLine($"'{dt1:yyyy-MM-dd hh:mm:ss}'");
Console.WriteLine($"'{dt2:yyyy-MM-dd hh:mm:ss}'");

เอาต์พุต: (ฉันใส่เครื่องหมายคำพูดเดี่ยวลงไปเพื่อให้คุณเห็นว่ามันกลับมาเป็นสตริงว่างเปล่าเมื่อว่าง)

'2019-04-09 08:01:39'
''
2019-04-09 08:01:39

'2019-04-09 08:01:39'
''

30

ดังที่คนอื่น ๆ ระบุไว้ว่าคุณต้องตรวจสอบค่าว่างก่อนที่จะเรียกใช้ ToString แต่เพื่อหลีกเลี่ยงการทำซ้ำตัวเองคุณสามารถสร้างวิธีการต่อเติมที่ทำเช่นนั้นได้ดังนี้:

public static class DateTimeExtensions {

  public static string ToStringOrDefault(this DateTime? source, string format, string defaultValue) {
    if (source != null) {
      return source.Value.ToString(format);
    }
    else {
      return String.IsNullOrEmpty(defaultValue) ?  String.Empty : defaultValue;
    }
  }

  public static string ToStringOrDefault(this DateTime? source, string format) {
       return ToStringOrDefault(source, format, null);
  }

}

ซึ่งสามารถเรียกเช่น:

DateTime? dt = DateTime.Now;
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss");  
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss", "n/a");
dt = null;
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss", "n/a")  //outputs 'n/a'

28

C # 6.0 ที่รัก:

dt2?.ToString("dd/MM/yyyy");


2
ฉันขอแนะนำรุ่นต่อไปนี้เพื่อให้คำตอบนี้เทียบเท่ากับคำตอบที่ยอมรับในปัจจุบันสำหรับ C # 6.0 Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss" ?? "n/a");
สามารถ Bud

15

ปัญหาเกี่ยวกับการกำหนดคำตอบสำหรับคำถามนี้คือคุณไม่ได้ระบุเอาต์พุตที่ต้องการเมื่อ datetime ที่ไม่มีค่าได้ไม่มีค่า รหัสต่อไปนี้จะแสดงผลDateTime.MinValueในกรณีดังกล่าวซึ่งแตกต่างจากคำตอบที่ยอมรับในปัจจุบันจะไม่ส่งข้อยกเว้น

dt2.GetValueOrDefault().ToString(format);

7

เมื่อเห็นว่าคุณต้องการให้รูปแบบที่ฉันแนะนำให้เพิ่มอินเทอร์เฟซ IFormattable ให้กับวิธีการส่วนขยายของ Smalls เช่นนั้นวิธีที่คุณไม่มีการต่อข้อมูลรูปแบบสตริงที่น่ารังเกียจ

public static string ToString<T>(this T? variable, string format, string nullValue = null)
where T: struct, IFormattable
{
  return (variable.HasValue) 
         ? variable.Value.ToString(format, null) 
         : nullValue;          //variable was null so return this value instead   
}


5

คุณสามารถใช้dt2.Value.ToString("format")แต่แน่นอนว่าต้องใช้ dt2! = null และนั่นเป็นการปฏิเสธการใช้ประเภท nullable ในครั้งแรก

มีวิธีแก้ไขปัญหาต่าง ๆ ที่นี่ แต่คำถามใหญ่คือ: คุณต้องการจัดรูปแบบnullวันที่ได้อย่างไร


5

นี่เป็นวิธีการทั่วไปมากขึ้น การทำเช่นนี้จะช่วยให้คุณสามารถจัดรูปแบบสตริงประเภทค่าที่เป็นโมฆะใด ๆ ฉันได้รวมวิธีที่สองเพื่ออนุญาตให้แทนที่ค่าสตริงเริ่มต้นแทนการใช้ค่าเริ่มต้นสำหรับประเภทค่า

public static class ExtensionMethods
{
    public static string ToString<T>(this Nullable<T> nullable, string format) where T : struct
    {
        return String.Format("{0:" + format + "}", nullable.GetValueOrDefault());
    }

    public static string ToString<T>(this Nullable<T> nullable, string format, string defaultValue) where T : struct
    {
        if (nullable.HasValue) {
            return String.Format("{0:" + format + "}", nullable.Value);
        }

        return defaultValue;
    }
}

4

คำตอบที่สั้นที่สุด

$"{dt:yyyy-MM-dd hh:mm:ss}"

การทดสอบ

DateTime dt1 = DateTime.Now;
Console.Write("Test 1: ");
Console.WriteLine($"{dt1:yyyy-MM-dd hh:mm:ss}"); //works

DateTime? dt2 = DateTime.Now;
Console.Write("Test 2: ");
Console.WriteLine($"{dt2:yyyy-MM-dd hh:mm:ss}"); //Works

DateTime? dt3 = null;
Console.Write("Test 3: ");
Console.WriteLine($"{dt3:yyyy-MM-dd hh:mm:ss}"); //Works - Returns empty string

Output
Test 1: 2017-08-03 12:38:57
Test 2: 2017-08-03 12:38:57
Test 3: 



2

ฉันคิดว่าคุณต้องใช้ GetValueOrDefault-Methode พฤติกรรมที่มี ToString ("yy ... ") ไม่ได้ถูกกำหนดไว้หากอินสแตนซ์นั้นเป็นโมฆะ

dt2.GetValueOrDefault().ToString("yyy...");

1
พฤติกรรมที่มี ToString ("yy ... ") จะถูกกำหนดหากอินสแตนซ์นั้นเป็นโมฆะเนื่องจาก GetValueOrDefault () จะส่งคืน DateTime.MinValue
Lucas

2

นี่คือคำตอบที่ยอดเยี่ยมของ Blake ในฐานะวิธีการขยาย เพิ่มสิ่งนี้ลงในโครงการของคุณและการโทรในคำถามจะทำงานได้ตามที่คาดไว้
ความหมายมันถูกใช้เช่นMyNullableDateTime.ToString("dd/MM/yyyy")กับผลลัพธ์เดียวกันเป็นMyDateTime.ToString("dd/MM/yyyy")ยกเว้นว่าค่าจะเป็น"N/A"ถ้า DateTime เป็นโมฆะ

public static string ToString(this DateTime? date, string format)
{
    return date != null ? date.Value.ToString(format) : "N/A";
}

1

IFormattable ยังรวมถึงผู้ให้บริการรูปแบบที่สามารถใช้งานได้ซึ่งช่วยให้รูปแบบ IFormatProvider ทั้งสองเป็น null ใน dotnet 4.0 ซึ่งจะเป็น

/// <summary>
/// Extentionclass for a nullable structs
/// </summary>
public static class NullableStructExtensions {

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider 
    /// If <c>null</c> the default provider is used</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. 
    /// If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format = null, 
                                     IFormatProvider provider = null, 
                                     string defaultValue = null) 
                                     where T : struct, IFormattable {
        return source.HasValue
                   ? source.Value.ToString(format, provider)
                   : (String.IsNullOrEmpty(defaultValue) ? String.Empty : defaultValue);
    }
}

ใช้ร่วมกับชื่อพารามิเตอร์ที่คุณสามารถทำได้:

dt2.ToString (defaultValue: "n / a");

ใน dotnet เวอร์ชั่นเก่าคุณจะได้รับจำนวนมาก

/// <summary>
/// Extentionclass for a nullable structs
/// </summary>
public static class NullableStructExtensions {

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider 
    /// If <c>null</c> the default provider is used</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. 
    /// If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, 
                                     IFormatProvider provider, string defaultValue) 
                                     where T : struct, IFormattable {
        return source.HasValue
                   ? source.Value.ToString(format, provider)
                   : (String.IsNullOrEmpty(defaultValue) ? String.Empty : defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="defaultValue">The string to show when the source is null. If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, string defaultValue) 
                                     where T : struct, IFormattable {
        return ToString(source, format, null, defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, IFormatProvider provider)
                                     where T : struct, IFormattable {
        return ToString(source, format, provider, null);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <returns>The formatted string or an empty string if the source is null</returns>
    public static string ToString<T>(this T? source, string format)
                                     where T : struct, IFormattable {
        return ToString(source, format, null, null);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, IFormatProvider provider, string defaultValue)
                                     where T : struct, IFormattable {
        return ToString(source, null, provider, defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, IFormatProvider provider)
                                     where T : struct, IFormattable {
        return ToString(source, null, provider, null);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source) 
                                     where T : struct, IFormattable {
        return ToString(source, null, null, null);
    }
}


0

นามสกุลทั่วไปอย่างง่าย

public static class Extensions
{

    /// <summary>
    /// Generic method for format nullable values
    /// </summary>
    /// <returns>Formated value or defaultValue</returns>
    public static string ToString<T>(this Nullable<T> nullable, string format, string defaultValue = null) where T : struct
    {
        if (nullable.HasValue)
        {
            return String.Format("{0:" + format + "}", nullable.Value);
        }

        return defaultValue;
    }
}

-2

อาจเป็นคำตอบที่ช้า แต่อาจช่วยคนอื่นได้

ง่าย ๆ คือ:

nullabledatevariable.Value.Date.ToString("d")

หรือใช้รูปแบบใดก็ได้แทน "d"

ดีที่สุด


1
ข้อผิดพลาดนี้จะเกิดขึ้นเมื่อ nullabledatevariable.Value เป็นโมฆะ
John C

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.