bpm 5.4 on-site
В базе данных хранится, например, 11 ч 41 мин, а в карточке отображается 18 ч 41, т.е. не учитывает мой часовой пояс. Как это исправить?
Нравится
о да)
это вечная проблема всех версий ТС
Даже тут, на форуме, часовой пояс сообщений не учитывается
я пишу по московскому времени, а отображается на форуме киевское время ...)
простите за флуд
мы у себя в ТС 3.х решали это тем, что просто использовали везде серверное время
плюс у SQL есть удобный формат даты с UTC
но у нас еще и проблема была в том, что у террасофт 3.х не разделено, где какое время будет использоваться с часовым поясом, а где без
и в результате, если использовать часовые пояса, то у нас, например, даты рождения контактов у некоторых людей становились не, допустим, 09.01.01 (00:00), а 08.01.01 22:00 )))
мило было)
Здравствуйте, Илья.
По умолчанию на клиенте время берется из браузера, который, в свою очередь, берет время из системных настроек.
В любом случае, Вы всегда можете установить конкретному пользователю определенный часовой пояс, тогда время для данного пользователя будет всегда устанавливаться согласно определенному часовому поясу:
В таблице SysAdminUnit у пользователя есть колонка TimeZoneId, куда Вы можете установить определенный часовой пояс из таблицы TimeZone, где хранятся все часовые пояса.
Например, следующим скриптом мы принудительно установим часовой пояс GMT+06:00 Новосибирск пользователю Supervisor:
update SysAdminUnit set TimeZoneId = (select Id from TimeZone where Name = '(GMT+06:00) Новосибирск') where Name = 'Supervisor'
"Соколов Илья Андреевич" написал:Версия 5.4, а не 3.х
"Калинин Иван" написал:мы у себя в ТС 3.х
я лишь привел пример и поделился опытом. я прекрасно видел, что ваша версия не 3.х
Здравствуйте, Илья.
Если проблема справедлива для раздела "Активности", прошу применить исправления ниже, предварительно выполнив резервную копию базы данных (!).
1. В схеме «ActivityUtils» найти статический метод «TryGetActivityPeriod» и заменить его содержимое, чтобы получилось так:
public static bool TryGetActivityPeriod(UserConnection userConnection, NameValueCollection queryString, HttpServerUtility server, out DateTime startDate, out DateTime dueDate) { bool result = false; var currentDateTime = userConnection.CurrentUser.GetCurrentDateTime(); startDate = currentDateTime; dueDate = currentDateTime; string startDateString = queryString[StartDateKey]; string dueDateString = queryString[DueDateKey]; if (!string.IsNullOrEmpty(startDateString) && !string.IsNullOrEmpty(dueDateString)) { result = DateTime.TryParse(server.UrlDecode(startDateString), CultureInfo.InvariantCulture, DateTimeStyles.None, out startDate) && DateTime.TryParse(server.UrlDecode(dueDateString), CultureInfo.InvariantCulture, DateTimeStyles.None, out dueDate); } return result; }
2. Сохранить изменения (НЕ ПУБЛИКОВАТЬ)
3. В процессе схемы «CallEditPage» найти ScriptTask «ChildPageLoadCompleteAfterBaseScript» (событие «PageLoadComplete» вызов после базового). В этой схеме заменить содержимое ScriptTask на:
if (IsNew) { var startDate = UserConnection.CurrentUser.GetCurrentDateTime(); var dueDate = UserConnection.CurrentUser.GetCurrentDateTime(); var periodFromQueryString = Terrasoft.Configuration.ActivityUtils.TryGetActivityPeriod(UserConnection, Page.Request.QueryString, Page.Server, out startDate, out dueDate); var defValues = Terrasoft.Configuration.ActivityUtils.GetActivityDefValues(UserConnection); var dataSource = Page.DataSource; dataSource.ActiveRow.SetColumnValue("StartDate", !periodFromQueryString ? startDate : defValues.StartDate); dataSource.ActiveRow.SetColumnValue("DueDate", !periodFromQueryString ? dueDate : defValues.DueDate); dataSource.ActiveRow.SetColumnValue("OwnerId", defValues.OwnerId); dataSource.ActiveRow.SetColumnValue("AuthorId", defValues.AuthorId); Page.StartDateEdit.SetValue(!periodFromQueryString ? startDate : defValues.StartDate); Page.DueDateEdit.SetValue(!periodFromQueryString ? dueDate : defValues.DueDate); Page.OwnerEdit.SetValueAndText(defValues.OwnerId, defValues.OwnerName); if (Page.Request.QueryString[Terrasoft.Configuration.ActivityUtils.ShowInScheduleKey] == bool.TrueString) { dataSource.ActiveRow.SetColumnValue("ShowInScheduler", true); Page.ShowInShedulerEdit.Checked = true; } } if (!(IsNew || IsCopy) && Page.DataSource.Rows[0].GetTypedColumnValue<bool>("Status_Finish")) { Page.ResultEdit.Enabled = true; Page.DetailedResultEdit.Enabled = true; } var allowedResult = Page.DataSource.ActiveRow.GetTypedColumnValue<string>("AllowedResult"); AllowedResults = string.IsNullOrEmpty(allowedResult) ? new Dictionary<Guid, string>() : JsonConvert.DeserializeObject<Dictionary<Guid, string>>(allowedResult); if (Page.DataSource.Rows.Count > 0) { Page.RemindToAuthorDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToAuthor"); Page.RemindToOwnerDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToOwner"); } return true;
4. Сохраняем изменения и сохраняем (НЕ ПУБЛИКУЕМ) схему процесса.
5. В процессе схемы «TaskEditPage» найти ScriptTask «ChildPageLoadCompleteAfterBaseScript» (событие «PageLoadComplete» вызов после базового). В этой схеме заменить содержимое ScriptTask на:
if (IsNew) { var startDate = UserConnection.CurrentUser.GetCurrentDateTime(); var dueDate = UserConnection.CurrentUser.GetCurrentDateTime(); var periodFromQueryString = Terrasoft.Configuration.ActivityUtils.TryGetActivityPeriod(UserConnection, Page.Request.QueryString, Page.Server, out startDate, out dueDate); var defValues = Terrasoft.Configuration.ActivityUtils.GetActivityDefValues(UserConnection); var dataSource = Page.DataSource; dataSource.ActiveRow.SetColumnValue("StartDate", !periodFromQueryString ? startDate : defValues.StartDate); dataSource.ActiveRow.SetColumnValue("DueDate", !periodFromQueryString ? dueDate : defValues.DueDate); dataSource.ActiveRow.SetColumnValue("OwnerId", defValues.OwnerId); dataSource.ActiveRow.SetColumnValue("AuthorId", defValues.AuthorId); Page.StartDateEdit.SetValue(!periodFromQueryString ? startDate : defValues.StartDate); Page.DueDateEdit.SetValue(!periodFromQueryString ? dueDate : defValues.DueDate); Page.OwnerEdit.SetValueAndText(defValues.OwnerId, defValues.OwnerName); if (Page.Request.QueryString[Terrasoft.Configuration.ActivityUtils.ShowInScheduleKey] == bool.TrueString) { dataSource.ActiveRow.SetColumnValue("ShowInScheduler", true); Page.ShowInSchedulerEdit.Checked = true; } } if (!(IsNew || IsCopy) && Page.DataSource.Rows[0].GetTypedColumnValue<bool>("Status_Finish")) { Page.ResultEdit.Enabled = true; Page.DetailedResultEdit.Enabled = true; } var allowedResult = Page.DataSource.ActiveRow.GetTypedColumnValue<string>("AllowedResult"); AllowedResults = string.IsNullOrEmpty(allowedResult) ? new Dictionary<Guid, string>() : JsonConvert.DeserializeObject<Dictionary<Guid, string>>(allowedResult); Page.CategoryEdit.Enabled = (AllowedResults as Dictionary<Guid, string>).Count == 0; if (Page.DataSource.Rows.Count > 0) { Page.RemindToAuthorDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToAuthor"); Page.RemaindToOwnerDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToOwner"); } return true;
6. Сохраняем изменения и сохраняем (НЕ ПУБЛИКУЕМ) схему процесса.
7. В процессе схемы «EmailEditPage» найти ScriptTask «EnableSendButton»/« Set Default Values, Activate Mail Send Button» (событие «PageLoadComplete» вызов после базового). В этой схеме заменить содержимое ScriptTask на:
if (IsNew) { var startDate = UserConnection.CurrentUser.GetCurrentDateTime(); var dueDate = UserConnection.CurrentUser.GetCurrentDateTime(); var periodFromQueryString = Terrasoft.Configuration.ActivityUtils.TryGetActivityPeriod(UserConnection, Page.Request.QueryString, Page.Server, out startDate, out dueDate); var defValues = Terrasoft.Configuration.ActivityUtils.GetActivityDefValues(UserConnection); var dataSource = Page.DataSource; dataSource.ActiveRow.SetColumnValue("StartDate", !periodFromQueryString ? startDate : defValues.StartDate); dataSource.ActiveRow.SetColumnValue("DueDate", !periodFromQueryString ? dueDate : defValues.DueDate); dataSource.ActiveRow.SetColumnValue("OwnerId", defValues.OwnerId); dataSource.ActiveRow.SetColumnValue("AuthorId", defValues.AuthorId); Page.StartDateEdit.SetValue(!periodFromQueryString ? startDate : defValues.StartDate); Page.DueDateEdit.SetValue(!periodFromQueryString ? dueDate : defValues.DueDate); Page.OwnerEdit.SetValueAndText(defValues.OwnerId, defValues.OwnerName); if (Page.Request.QueryString[Terrasoft.Configuration.ActivityUtils.ShowInScheduleKey] == bool.TrueString) { dataSource.ActiveRow.SetColumnValue("ShowInScheduler", true); Page.ShowInSchedulerEdit.Checked = true; } var parameterContactId = GetIdFromParameter("ContactId"); if (!parameterContactId.Equals(Guid.Empty)) { dataSource.ActiveRow.SetColumnValue("Recepient", GetRecipientByContact(parameterContactId)); } var parameterTemplateId = GetIdFromParameter("TemplateId"); if (!parameterTemplateId.Equals(Guid.Empty)) { /* Activity activity = GetActivity(); var condition = new Dictionary<string, object>() { { "Activity", activity.Id }, { "EmailTemplate", parameterTemplateId } }; var link = new EmailTemplateActivity(UserConnection); bool isFetched = false; try { isFetched = link.FetchFromDB(condition); } catch { continue; } if (!isFetched) { link.SetDefColumnValues(); link.ActivityId = activity.Id; link.EmailTemplateId = parameterTemplateId; link.Save(); } */ AddTemplateToEmailBody(parameterTemplateId, true); } } if (!IsNew && !IsCopy) { var emailStatusId = Page.DataSource.Rows[0].GetTypedColumnValue<Guid>("EmailSendStatusId"); var emailStatus_Sended = new Guid("8074FFC0-6107-E011-A646-16D83CAB0980"); var emailStatus_InProgress = new Guid("603BA6AF-6107-E011-A646-16D83CAB0980"); if(emailStatusId.Equals(emailStatus_Sended) || emailStatusId.Equals(emailStatus_InProgress)) { Page.EmailButton.Enabled = false; } if(emailStatusId.Equals(emailStatus_Sended)) { Page.SenderEdit.Enabled = false; Page.RecepientEdit.Enabled = false; Page.CopyRecepientEdit.Enabled = false; Page.BlindCopyRecepientEdit.Enabled = false; Page.TitleEdit.Enabled = false; Page.OwnerEdit.Enabled = false; Page.StatusEdit.Enabled = false; Page.BodyEdit.Enabled = false; } } Page.AddTemplateButton.Enabled = !IsNew && !IsCopy; Page.CreateMessageFromTemplatesButton.Enabled = !IsNew && !IsCopy; if (Page.DataSource.Rows.Count > 0) { Page.RemindToAuthorDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToAuthor"); Page.RemindToOwnerDateEdit.Enabled = Page.DataSource.Rows[0].GetTypedColumnValue<bool>("RemindToOwner"); } return true;
8. Сохраняем изменения, и ПУБЛИКУЕМ схему. (Подтянется публикация измененных схем при компилировании конфигурации).
9. Проверяем.
Все.
Нет, это не раздел активности. Я создал свой раздел.
Нет, это не раздел активности. Я создал свой раздел.
Нет, это не раздел активности. Я создал свой раздел.
Илья, проблемы со временем только в Вашем разделе или во всех разделах системы?
Илья,
проблема в том, что в базе данные хранятся в UTC формате, а затем у каждого пользователя отображаются в соответствии с часовым поясом его браузера.
В Ваш раздел данные попадают напрямую SQL-запросом и уже в базу они сохраняются со смещением согласно Вашему часовому поясу.
Решением является писать записи в Ваш раздел в формате UTC. Для этого существуют функция SQL:
GETUTCDATE()
Працюю з версією 5.4
Намагаюсь розібратися з часовим поясом.
Формую в SQL вибірку для формування звіту.
В базі дати зберігаються як UTC.
Витягую значення
var offSet=UserConnection.CurrentUser.TimeZone.BaseUtcOffset.TotalMinutes
яке в SQL-запиті підставляю в дати:
DATEADD(MINUTES,offSet,<дата>)
Все добре, окрім одного:
UserConnection.CurrentUser.TimeZone.DisplayName =>
displayName : (UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
але по карточці звернення бачу, що зміщення не +2:00, а +3:00
Поки що не знайшов, як вийти на +3:00
"Зверев Александр" написал:Видимо, ещё один час даёт летнее время.
Може й так, але яким чином та година враховується ?
В одному скрипті я отримую значення:
var respondedOn = activeRow.GetTypedColumnValue<DateTime>("RespondedOn");
та
var offSet = UserConnection.CurrentUser.TimeZone.BaseUtcOffset.TotalMinutes;
respondedOn враховує +3:00
а
offSet = 120
Тут пишут, что для часового пояса можно получить, переводят ли часы:
Use TimeZoneInfo.IsDaylightSavingTime Method (DateTimeOffset) to find if it is currently Daylight saving for your Timezone.var info = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time"); DateTimeOffset localServerTime = DateTimeOffset.Now; bool isDaylightSaving = info.IsDaylightSavingTime(localServerTime);There are further examples here