Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Автоматическое вычисление разности дат в поле 
V
    Опции темы
ViterAlex
Дата 10.11.2009, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 7.10.2009
Где: Харьков

Репутация: нет
Всего: 7



Есть DataTable, у которой два поля (StartTime и StopTime) имеют формат System.DateTime. Прекрасно отображаются в DataGridView. Нужно сделать ещё одно поле, которое бы отображало разницу между этими двумя полями. Я так понимаю, что поле должно быть System.TimeSpan, но как в него записывать значения? Очень бы хотелось это делать автоматически, через Expression 
Пробовал при создании поля записывать так:
Код
column = New DataColumn
With column
  .ColumnName = "CountdownTime"
  .Caption = "Продолжительность"
  .DataType = GetType(System.TimeSpan)
  .Expression = "IIF(StopTime Is Null, Null, StopTime - StartTime)"
End With
dt.Columns.Add(column)

Если StopTime пустое, то ошибок нет (какие могут быть ошибки?smile), а вот если нужно посчитать разницу, то дает ошибку:
Цитата

Невозможно выполнить операцию "-" над System.DateTime и System.DateTime.

Как быть?
P.S. Пишу пока что на VB.Net smile
PM MAIL WWW ICQ   Вверх
KuMa1104
Дата 10.11.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: 1
Всего: 3



Привет!
Ух не силён я в VB.

Попробуй так, это стандартный способ. Это на C# но на VB  по аналогии, обекты ведь одинаковые.
user posted image
В твоем случае видимо тип Time  или как он там называеться, и StopTime - StartTime видимо.И он для каждой строки по идее должен прогнать.


--------------------
Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время - штука относительная... а время обеда - ещё более относительная
PM MAIL   Вверх
ViterAlex
Дата 10.11.2009, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 7.10.2009
Где: Харьков

Репутация: нет
Всего: 7



Понимаешь, для обычных чисел считает без вопросов. У меня есть в таблице такой столбец-выражение для Double, но именно для даты, вернее для разности дат, не хочет. Попробуй сделать для дат, может у тебя получится.
PM MAIL WWW ICQ   Вверх
KuMa1104
Дата 11.11.2009, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: 1
Всего: 3



Попробовал тоже вылетает оно.
Почитал сдесь
 http://www.sql.ru/forum/actualthread.aspx?tid=662554

наверное прийдёться, заполнять уже после пробегаясь по каждой строке.
Но если получиться по другому то напиши, аж самому интересно))


--------------------
Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время - штука относительная... а время обеда - ещё более относительная
PM MAIL   Вверх
mrbrooks
Дата 11.11.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(ViterAlex @  10.11.2009,  13:17 Найти цитируемый пост)
Как быть?

предлагаю такой подход - отображение времени - это функция клиента.
конкретнее - хранить метку времени в БД , как длинное целое (тот же UTC) и уже собственно работать именно с ним. 
покажу на примере:

Код

            DataTable dt = new DataTable("test_table");
            DataColumn dc_id = new DataColumn("id", typeof(Int32));
            dc_id.AutoIncrement = true;
            dc_id.AutoIncrementSeed = 0;
            dc_id.AutoIncrementStep = 1;
            dt.Columns.Add(dc_id);
            try
            {
                dt.Columns.Add("StartTime", typeof(Int64));
                dt.Columns.Add("StopTime", typeof(Int64));
                dt.Columns.Add("SubTime", typeof(Int64), "StopTime - StartTime");
                DateTime dt_def = DateTime.Now;
                for (int i = 0; i < 5; i++)
                {

                    DataRow dr = dt.NewRow();
                    dr[1] = dt_def.ToFileTimeUtc();
                    dr[2] = dt_def.Add(new TimeSpan(i, 27 * i, 58 * i)).ToFileTimeUtc();
                    dt.Rows.Add(dr);
                    Console.WriteLine("{0} | {1} | {2} | {3} |", 
                                      dr[0], 
                                      new DateTime((Int64)dr[1]), 
                                      new DateTime((Int64)dr[2]), 
                                      new TimeSpan((Int64)dr[3]));
                }
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }



бесспорно это не оптимальный вариант. писал на скорую руку. но тем не менее он подчеркивает мою мысль.
PM MAIL   Вверх
ViterAlex
Дата 11.11.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 7.10.2009
Где: Харьков

Репутация: нет
Всего: 7



mrbrooks, ты прав. Всё получилось. 
А как, вернее, когда правильно форматировать выводимые значения? Я делаю это в CellFormating. Может есть другой метод?
PM MAIL WWW ICQ   Вверх
mrbrooks
Дата 13.11.2009, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(ViterAlex @  11.11.2009,  23:13 Найти цитируемый пост)
Я делаю это в CellFormating. 

 данное событие собственно для этого и создано.
PM MAIL   Вверх
advantiss1
Дата 17.12.2009, 11:31 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



К сожалению DataColumn.Expression имеет очень ограниченный список поддерживаемых функций, к тому же сделать для него extensible метод проблематично. 
Как вариант - выполнять расчет в обработчиках событий DataTable.ColumnChanged, DataTable.RowChanged. Это позволит не извращать формат хранения данных в БД под данный кусочек логики.
PM MAIL   Вверх
ViterAlex
Дата 17.12.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 7.10.2009
Где: Харьков

Репутация: нет
Всего: 7



А почему извращать? Всё наоборот, очень логично. Храним число, делаем с ним, что нужно, а когда нужно его показать, то форматируем.
PM MAIL WWW ICQ   Вверх
advantiss1
Дата 17.12.2009, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(ViterAlex @ 17.12.2009,  11:55)
А почему извращать? Всё наоборот, очень логично. Храним число, делаем с ним, что нужно, а когда нужно его показать, то форматируем.

Дело в том, что потом придется выполнять преобразование данных при каждом обращении к ним, как в SQL запросах так и в логике.
Для того и выделены различные типы данных, чтоб было удобно ими пользоваться разработчику.  В данном случае хранение даты в формате числа является решением одной локальной проблемы(что есть хак в чистом виде), влекущей за собой глобальные последствия  smile 

PM MAIL   Вверх
mrbrooks
Дата 17.12.2009, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(advantiss1 @  17.12.2009,  12:50 Найти цитируемый пост)
Дело в том, что потом придется выполнять преобразование данных при каждом обращении к ним, как в SQL запросах так и в логике.

При чем здесь SQL? Данные пересчитывает клиент при отображении/записи. Этим приемом пользуются в частности производители промышленных девайсов. К примеру если брать устройства по архиву данных - в них время хранится всегда как длинное целое в UTC.

Цитата(advantiss1 @  17.12.2009,  12:50 Найти цитируемый пост)
В данном случае хранение даты в формате числа является решением одной локальной проблемы(что есть хак в чистом виде), влекущей за собой глобальные последствия 

Чем богаты, тому и рады.
PM MAIL   Вверх
advantiss1
Дата 17.12.2009, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(mrbrooks @  17.12.2009,  13:53 Найти цитируемый пост)
При чем здесь SQL? Данные пересчитывает клиент при отображении/записи. Этим приемом пользуются в частности производители промышленных девайсов. К примеру если брать устройства по архиву данных - в них время хранится всегда как длинное целое в UTC.


к примеру:
вместо 
Код

WHERE
   date_fied BETWEEN (@date1 AND @date2)


прийдется писать

Код

WHERE
   date_field BETWEEN (CAST(@date1 AS decimal ) AND CAST(@date2 AS decimal ))


или

Код

WHERE
    CAST (date_fied AS date) BETWEEN (@date1 AND @date2)


также очевидно что CAST добавляет лишней работы серверу БД, что для выборок на больших обьемах данных, будет давать "прирост" во времени выполнения запроса


Но в конце концов, соглашусь, вариант хранения даты в виде числа можно принять как одно из решений проблемы, дело вкуса.

Это сообщение отредактировал(а) advantiss1 - 17.12.2009, 15:14
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1130 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.