none
疑难问题,关于datatable.select datetime国际化问题,难! RRS feed

  • 问题

  • 需要解决的问题是,在一个datatable中选择出一个时间范围内的datarow数组。
    当操作系统的区域和语言选项为中文中国及英语美国时,下面的代码运行正常。
    但是在德语德国下,下面的语句抛出异常
    DataRow[] rows = dt.Select(filterExpression);
    该字符串未被识别为有效的 DateTime。很长时间一直得不到解决,请高手及Microsoft工程师帮忙解决下,谢谢。

    下面是代码

    private DataTable CreateDatatable()
        {
          using (DataTable dt = new DataTable())
          {
            dt.Columns.Add("datetime", typeof(DateTime));
            dt.Columns.Add("value", typeof(double));
            return dt;
          }
        }
    
        private void Main_Load(object sender, EventArgs e)
        {
          dateTimePicker2.Value = System.DateTime.Now.AddDays(365);
    
          string dateTimeFormat=System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern;
          dateTimePicker1.CustomFormat = dateTimeFormat;
          dateTimePicker2.CustomFormat = dateTimeFormat;
    
          System.Random randow = new Random();
          System.Globalization.Calendar calendar = System.Globalization.CultureInfo.CurrentCulture.Calendar;
          DataRow dataRow = null;
          using (DataTable dt = CreateDatatable())
          {
            dataRow = dt.NewRow();
            dataRow[0] = new DateTime(2010, 11, 17, 9, 31, 20, calendar);
            dataRow[1] = randow.NextDouble();
            dt.Rows.Add(dataRow);
    
            dataRow = dt.NewRow();
            dataRow[0] = new DateTime(2010, 11, 18, 12, 24, 11, calendar);
            dataRow[1] = randow.NextDouble();
            dt.Rows.Add(dataRow);
    
            DateTime sTime=dateTimePicker1.Value;
            DateTime eTime=dateTimePicker2.Value;
    
            string filterExpression = string.Format("datetime>=#{0}# and datetime<=#{1}#", sTime, eTime);
    
            DataRow[] rows = dt.Select(filterExpression);
          }
        }
    
    2010年11月11日 2:10

答案

  • Hi heywap,

    不好意思,周五走得早,没回复您的邮件,解决方法其实很简单,无论在哪种Locale(CultureInfo)下,将当前的datetime format成CultureInfo.InvariantCulture ,再代入到DataTable.Select方法里,没有任何问题。

     

    先把DateTimePicker的Value设成this.dateTimePicker1.Value = DateTime.UtcNow ;,然后参考下面的code:

     

    DateTime localTime = this
    .dateTimePicker1.Value;
    String sTime = String.Empty, eTime = String.Empty;
    try
    
    {
    	sTime = localTime.ToString(CultureInfo.InvariantCulture);
    	eTime = localTime.AddDays(2d).ToString(CultureInfo.InvariantCulture);
    }
    catch
    
     (FormatException ex)
    {
    	// Handle ex
    
    	return;
    
    }
    
    string
     filter = string
    .Format("datetime>=#{0}# and datetime<=#{1}#"
    , sTime,eTime);
    DataRow[] rows = dt.Select(filter);
    

     

    希望您的问题 解决:)

     

    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website:   http://WayneYe.com


    • 已标记为答案 heywap 2010年11月16日 13:51
    2010年11月15日 2:31

全部回复

  • Hi heywap,

    我曾经遇到过类似的问题,refer: http://wayneye.com/ViewBlog.aspx?BlogID=72


    这个问题是由于不同locle下datetime的格式不同造成的,您在英文下使用Select方法传入的filterformat只能适用于部分区域 ,所以合理的做法应该是:

    1. 将数据库里的datetime数据转换成UTC格式或者任意一种确定的格式(en-US, zh-CN, fr-FR, etc)。

    2. 在Select方法里传入UTC格式或您之前转换后的一种确定的格式

     

    参考MSDN:

    Custom Date and Time Format Strings

    http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx


    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website:   http://WayneYe.com


    • 已建议为答案 mazhou 2010年11月11日 12:17
    2010年11月11日 4:05
  • to:Wayne ElemenT

    感谢您的回复。您说的方法非常好用。

    我现在的做法就是将datetime使用ToUniversalTime()方法后保存到datatable中的。

    但是因为保存在datatable中的是utc格式的,所以显示时不能显示为本地格式的时间,请问有什么好办法,在datagridview中显示本地的时间。我的代码如下:

    DataRow[] rows = dt.Select(filterExpression);
            DataGridViewRow dgvr = null;
    
            for (int i = 0; i < rows.Length; i++)
            {
              dgvr = new DataGridViewRow();
              dgvr.CreateCells(this.dataGridView1, rows[i].ItemArray);
              this.dataGridView1.Rows.Add(dgvr);
            }
    
    2010年11月11日 7:44
  • Hi 

    Thanks for your post!


    Datetime.Now.ToLocalTime() 不知是不是您想要的?


    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website:   http://WayneYe.com


    2010年11月11日 7:47
  • Hi heywap,

    我曾经遇到过类似的问题,refer: http://wayneye.com/ViewBlog.aspx?BlogID=72


    这个问题是由于不同locle下datetime的格式不同造成的,您在英文下使用Select方法传入的filterformat只能适用于部分区域 ,所以合理的做法应该是:

    1. 将数据库里的datetime数据转换成UTC格式或者任意一种确定的格式(en-US, zh-CN, fr-FR, etc)。

    2. 在Select方法里传入UTC格式或您之前转换后的一种确定的格式

     

    参考MSDN:

    Custom Date and Time Format Strings

    http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx


    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website:   http://WayneYe.com



    居然看到了你的帖子,欢迎加入 MSDN C# 专家家庭!
    Mark Zhou
    2010年11月11日 12:17
  • to:Wayne ElemenT

    感谢您给予我的无私帮助。

    情况发生了点变化,您今天给出的思路,我写demo时一切正常。可是用在项目中的时候却还是遇到是相同的问题,太奇怪了。这个问题已经困扰我两天的时间了,相当的不爽。不知道您是否愿意帮我查找和分析一下代码。如果您愿意的话,我可以发布到一个web地址,您下载下。谢谢。

    2010年11月11日 13:47
  • Hi heywap,

    您的情况咱们做程序员的都能理解,我也经常卡1,2天结果发现一个极小的地方粗心了,多多努力这种问题就会越来越少发生。

     

    我的MSN是:xiaotianpop@msn.com

     

    一起学习交流吧~~:)


    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website: http://WayneYe.com


    2010年11月11日 14:19
  • To Mark,

    呵呵,一起交流吧,我混E文坛子稍微多点,中文的也关注。

    2010年11月11日 14:20
  • to:Wayne ElemenT

    给您留下的email发了一个小的demo,您看下。麻烦您了。

    一个小问题困扰三天,无奈 啊

    2010年11月12日 7:29
  • Hi heywap,

    不好意思,周五走得早,没回复您的邮件,解决方法其实很简单,无论在哪种Locale(CultureInfo)下,将当前的datetime format成CultureInfo.InvariantCulture ,再代入到DataTable.Select方法里,没有任何问题。

     

    先把DateTimePicker的Value设成this.dateTimePicker1.Value = DateTime.UtcNow ;,然后参考下面的code:

     

    DateTime localTime = this
    .dateTimePicker1.Value;
    String sTime = String.Empty, eTime = String.Empty;
    try
    
    {
    	sTime = localTime.ToString(CultureInfo.InvariantCulture);
    	eTime = localTime.AddDays(2d).ToString(CultureInfo.InvariantCulture);
    }
    catch
    
     (FormatException ex)
    {
    	// Handle ex
    
    	return;
    
    }
    
    string
     filter = string
    .Format("datetime>=#{0}# and datetime<=#{1}#"
    , sTime,eTime);
    DataRow[] rows = dt.Select(filter);
    

     

    希望您的问题 解决:)

     

    Please feel free to let me know if you have any further issues, thanks!



    Happy Coding:)
    Wayne Ye - Senior Software Development Engineer
    Personal Website:   http://WayneYe.com


    • 已标记为答案 heywap 2010年11月16日 13:51
    2010年11月15日 2:31
  • 十分感谢 Wayne ElemenT 一直以来给予我的无私帮助。谢谢。

    问题已经得到解决。

    2010年11月16日 13:51
  • You are so welcome:)

    2010年11月16日 15:20
  • To Mark,

    呵呵,一起交流吧,我混E文坛子稍微多点,中文的也关注。


    我一般在中文 C# 论坛呆的时间比较长一些,英文的人太多了,不需要我了,:)

    中文 C# 论坛人气还有待于提升,希望大家多多努力。


    Mark Zhou
    2010年11月17日 6:43