Страницы

Поиск по вопросам

пятница, 26 октября 2018 г.

Mysql возвратить время со сдвигом timezone

Есть ли способ возвращать время в зависимости от временной зоны? Я понимаю что есть timestampz, но в данном случае datetime
т.е. хочу получить время по москве (3) исходя из текущего сохраненного (5) где время по москве 14:00
select dt_create + interval 2 hour from t where dt_create - interval 2 hour = 14:00
но загвоздка в том, что я не знаю какие поля - это время. могу ли я в зависимости от типа поля добавлять интервал?


Ответ

Часовые пояса относятся к уровню презентации. Большинство вашего кода не должно заниматься часовыми поясами или местным временем, оно должно передавать Unix-время как оно есть. Когда измеряете время, измеряйте Unix-время. Это UTC. Его просто получить (системными функциями). Оно не имеет часовых поясов или летнего времени (и високосных секунд). Когда храните время, храните Unix-время. Это одно число. Если вы хотите сохранить время, пригодное для чтения человеком (например, в логах), постарайтесь сохранить его вместе с Unix-временем, а не вместо. Когда отображаете время, всегда включайте в него смещение часового пояса. Формат времени без смещения бесполезен. Системные часы не точны. Вы в сети? Системные часы каждой другой машины не точны по-разному. Системные часы могут, и будут, перепрыгивать вперёд и назад во времени из-за вещей, которые вне вашего контроля. Ваша программа должна быть разработана таким образом, чтобы пережить это. Отношение количества секунд системных часов к количеству настоящих секунд — не точно и может меняться. В основном это зависит от температуры. MySQL хранит столбцы типа DATETIME в виде упакованных в числа значений «YYYYMMDD HHMMSS» Если вы озаботились хранением отметок времени, храните их как целое число и используйте для преобразования функции UNIX_TIMESTAMP() и FROM_UNIXTIME().
Что должен знать о времени каждый программист

Как положить свой ProjectTemplate в раздел VisualSudio (Visual C#/Web)?

Привет! Я пытаюсь затолкать свой шаблон проекта в (Visual C#/Web)(Аналогично тому как там лежит DevExpress Template Gallery на моём скриншоте). Пытаюсь сделать это следующими строками кода в файле MyTemplate.vstemplate:
My Template Gallery Start Template Gallery myProj.ico CSharp Web Web 4.0 0 0 4d72892d-abc3-428d-8fa7-8421a83d6e0a true XafariApplication true


Ответ

Ручной способ
Создаете проект. Заполняете нужными начальными файлами для шаблона. Сохраняете.
В меню Файл выбираете Экспорт шаблона. В Wizard'е выбираете: Project Template. Заполняете поля. Архив закинется в папку <Рабочая папка студии>\My Exported Templates и в папку <Рабочая папка студии>\Templates\ProjectTemplates (если не сняли галку в wizard'е): Этот архив нужно поместить в папку <Рабочая папка студии>\Templates\ProjectTemplates\Visual C#\Web (ее нет, поэтому необходимо создать): Заходите в студию. И Profit.
С помощью VSIX
Дожен быть готов архив. Смотри 1-5 пункты ручного способа Создаете проект VSIX. В проекте создаете нужную иерархию папок. В данном случае получается следующая иерархия: Закидывайте архив в папку ProjectTemplates\CSharp\Web В манифесте указываете нужные данные. Затем заходите в пункт Assets и добавляете: Сохраняетесь. Билдитесь. Запускаете VSIX. Открываете студию.
ProjectTemplate + VSIX
Создаете проект типа ProjectTemplate заполняете его. Выбираете в студии файл с расширением *.vstemplate (по умолчанию его имя совпадает с именем проекта). И в его свойствах в строке Category прописываете путь иерархии, который будет начинаться от CSharp. Т.е. если указываете SubA/SubB/SubC, то шаблон будет лежать в CSharp/SubA/SubB/SubC. В нашем случае указываем только Web: Создаем проект VSIX. В манифесте указываете нужные данные: Билдитесь.
P.S. Немного про элемент TemplateData. Вы указали ProjectSubType значение Web, но этот элемент может иметь только всего 4 значения:
SmartDevice-NETCFv1 - указывает поддержку .NET Compact Framework версии 1.0 SmartDevice-NETCFv1 - указывает поддержку .NET Compact Framework версии 2.0 CSharp - Задается только тогда, когда элемент ProjectType имеет значение Web (т.е. это проект типа веб-сайт). Указывает на языка программирования. VisualBasic - тоже самое, что и предыдущий пункт, только язык программирования VisualBasic

Почему съедает слеш в скобочной группе регулярного выражения?

.htaccess
RewriteRule ^activation-account/(.+)/login([a-zA-Z0-9_]+)$ web/index.php?r=registration/activation-register/activation&key_active=$1&key_login=$2 [L]
Переходим по ссылке http://myhost//activation-account/$2y$10$Xl40W/SKTOXYcxfCxGszr.9tbd//lNJSVJTpBh4umjWf/9GNMSlJy/loginfiko
Ловим переменную в php key_active
Она возвращает: $2y$10$Xl40W/SKTOXYcxfCxGszr.9tbd/lNJSVJTpBh4umjWf/9GNMSlJy
То есть на этом промежутке 9tbd/l убирается слеш а должно быть так 9tbd//l


Ответ

Вот рабочий вариант редиректа для Apache:
RewriteEngine On RewriteCond %{REQUEST_URI} ^/*activation-account/(.+)/login(\w+)$ RewriteRule .* web/index.php??r=registration/activation-register/activation&key_active=%1&key_login=%2 [L]
В переменных запроса он ни чего не имеет против двойного слеша.
UPD + мой ответ на вопрос: Как сделать всё и сразу в mod_rewrite?

Добавить текст в строку ввода

Приветствую. Хочу сделать возможность редактирование переменной, но не нашел функции для добавления текста уже имеющегося значения в строку ввода консоли, для его редактирования. Не подскажете функцию?
P.S Вопрос глупый, но гугл ничего не выдает из-за засилия других глупых вопросов.


Ответ

Вот (довольно искусственный) пример использования GNU readline на Си (также компилируется и g++) (а вот ссылка на нее для windows)
Программа анализирует прочитанную строку и если в ней есть слово, начинающееся с V:, то оно подставляется для ввода следующей строки.
#include #include #include #include
static char *ins;
int f() { if (ins && ins[0]) { rl_insert_text(ins); rl_redisplay(); } }
int main (int ac, char *av[]) { char *line = 0, txt[1000] = "", *p;
rl_pre_input_hook = f; // readline() вызовет нашу функцию перед чтением ввода (после вывода промпта) rl_bind_key('\t', rl_insert); // для вставки символа табуляции (иначе он работает как поиск дополнения имени файла) ins = txt;
while (line = readline("> ")) { printf("line: %s
", *line ? line : ""); txt[0] = 0; if (p = strstr(line, "V:")) sscanf(p, "%s", txt);
if (line[0]) add_history(line);
free(line); }
return puts("End") == EOF; }
Поскольку вложенные функции не поддерживаются в С++ функцию f() (readline hook) и массив char txt[] (или указатель на него, как в этом примере) приходится выносить на внешний уровень.
Пример вызова:
avp@avp-ubu1:hashcode$ g++ t-readline.c -lreadline avp@avp-ubu1:hashcode$ ./a.out > ksdkk line: ksdkk > ueru V:444 line: ueru V:444 > V:444 kksk line: V:444 kksk > End
В строке 5 (третий вызов readline) текст V:444 в начале области ввода подставлен из предыдущей введенной строки.

Отрисовать пиксели на Xorg-окне с помощью стандартных либ в Linux

Графические тулкиты штука сложная, но все они начинают с отрисовки пикселя, мне нужно повторить это базовое действие. Допустим имеется запущенный Xorg, в нём программа, которая любым образом создаёт себе Xorg-окно, в этом окне и нужно рисовать пиксели.
Условие:
Только стандартные библиотеки ядра Linux. Никаких GTK/Qt/OpenGL/Cairo и встроенных Xorg-способов.
Вопросы:
Чем, собственно, рисовать? (Хотелось бы услышать конкретный ответ.) Как рисовать? (Желательны примеры/ссылки на примеры, тема довольно непопулярная, информации мало.) Преимущества того или иного способа.
UPD: В ответ на комментарий пользователя @KoVadim всё не влезло, отпишу в основной вопрос в качестве общего пояснения.
Если это Xorg окно, то и он должен рисовать с помощью XDrawPoint
Хочется сказать, что большинство граф. тулкитов не рисует картинку через фичи графического сервера. Qt рисует с помощью своего "велосипеда", GTK это делает с помощью Cairo, и это правильно. В том же Wayland, который пришел в замену иксов вообще нет подобного функционала. Wayland просто делает окно оставляя отрисовку всего в окне тулкитам.
Остановимся на Cairo, он наверняка использует что-то низкоуровневое, я хочу узнать что. (копать сорцы опыта не хватает)
Фреймбуфер пробовал, всё про него знаю. Во первых лучше использовать DRM. Во вторых это всё не то. (А возможно DRM вполне годен, но как его использовать а Xorg я не нашел, нету документации и всё.)


Ответ

LibXCB считается более современной и более производительной, чем xlib, но документация по ней не полная. Рисовать что-то по пикселам очень непроизводительно, поэтому есть набор примитивов, часть которых обычно поддерживается аппаратно. Там есть пример рисования некоторых примитивов кроме пиксмапов. Cairo использует libXCB.
Кстати если разберётесь, может быть ответите на мой вопрос четырёхлетней давности?

Построение кривой Серпинского без использования рекурсии

Доброго времени суток.
Необходимо реализовать рекурсивную и нерекурсивную реализацию построения кривой Серпинского.
Рекурсивное построение не составило большого труда, а вот найти конечный алгоритм для нерекурсивной реализации (понятный для имплементации) не получилось (Только в книге Род Стивене - "Delphi Готовые алгоритмы").
Может ли кто-нибудь скинуть материалы где можно почитать про нерекурсивную имплементацию построения кривых Серпинского?
Реализация Рекурсивного алгоритма:
static private void Sierpinski(int depth, float dx, float dy, Graphics gr = null){ float x = dx; float y = dy; drawA(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, dy); drawB(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, dy); drawC(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, -dy); drawD(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, -dy); }
static private void drawA(Graphics gr, int depth, ref float x, ref float y, float dx, float dy) { if (depth > 0) { --depth; drawA(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, dy); drawB(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, 2 * dx, 0); drawD(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, -dy); drawA(gr, depth, ref x, ref y, dx, dy); } }
static private void drawB(Graphics gr, int depth, ref float x, ref float y, float dx, float dy) { if (depth > 0) { --depth; drawB(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, dy); drawC(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, 0, 2 * dy); drawA(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, dy); drawB(gr, depth, ref x, ref y, dx, dy); } }
static private void drawC(Graphics gr, int depth, ref float x, ref float y, float dx, float dy) { if (depth > 0) { --depth; drawC(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, -dy); drawD(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -2 * dx, 0); drawB(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, dy); drawC(gr, depth, ref x, ref y, dx, dy); } }
static private void drawD(Graphics gr, int depth, ref float x, ref float y, float dx, float dy) { if (depth > 0) { --depth; drawD(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, dx, -dy); drawA(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, 0, -2 * dy); drawC(gr, depth, ref x, ref y, dx, dy); drawLine(gr, ref x, ref y, -dx, -dy); drawD(gr, depth, ref x, ref y, dx, dy); } }
Реализация функции drawLine()
static private void drawLine(Graphics gr, ref float x, ref float y, float dx, float dy) { if (gr != null) gr.DrawLine(Pens.Black, x, y, x + dx, y + dy); x += dx; y += dy; }


Ответ

Воспользуемся стандартным подходом: перепишем функцию в виде набора заданий и управляющего цикла, который выполняет задания по одному. Вместо рекурсивного вызова функций будем добавлять новые задания в стек этих самых заданий. Этим самым мы как бы заменяем стек вызовов стеком заданий.
Для нашего случая, заведём структуру данных, описывающую одно задание. Одним заданием у нас будет вызов drawA, drawB, drawC, drawD или drawLine. Получаем следующую структуру:
struct DrawTask { public DrawTask(char type, int depth, float dx = 0, float dy = 0) { Type = type; Depth = depth; Linedx = dx; Linedy = dy; }
public char Type; // A, B, C, D или L public int Depth; public float Linedx; // эти параметры нужны лишь для задания типа L public float Linedy; }
Теперь нам нужна очередь заданий и её интерпретатор:
static void Sierpinski_NR(int depth, float dx, float dy, Graphics gr = null) { Stack taskStack = new Stack(); float x = dx; float y = dy;
// загружаем задания в стек в обратном порядке taskStack.Push(new DrawTask('L', depth, dx, -dy)); taskStack.Push(new DrawTask('D', depth)); taskStack.Push(new DrawTask('L', depth, -dx, -dy)); taskStack.Push(new DrawTask('C', depth)); taskStack.Push(new DrawTask('L', depth, -dx, dy)); taskStack.Push(new DrawTask('B', depth)); taskStack.Push(new DrawTask('L', depth, dx, dy)); taskStack.Push(new DrawTask('A', depth));
// пока есть задание, достаём его и выполняем // в результате выполнения в стеке могут оказаться подзадания while (taskStack.Count > 0) { var currentTask = taskStack.Pop(); switch (currentTask.Type) { case 'A': drawA_NR(gr, currentTask.Depth, ref x, ref y, dx, dy, taskStack); break; case 'B': drawB_NR(gr, currentTask.Depth, ref x, ref y, dx, dy, taskStack); break; case 'C': drawC_NR(gr, currentTask.Depth, ref x, ref y, dx, dy, taskStack); break; case 'D': drawD_NR(gr, currentTask.Depth, ref x, ref y, dx, dy, taskStack); break; case 'L': drawLine(gr, ref x, ref y, currentTask.Linedx, currentTask.Linedy); break; } } }
Процедуру A имплементируем таким же образом. Она сама не делает ничего, просто добавляет в стек подзадания:
static void drawA_NR(Graphics gr, int depth, ref float x, ref float y, float dx, float dy, Stack taskStack) { if (depth > 0) { --depth;
// помещаем в стек в обратном порядке taskStack.Push(new DrawTask('A', depth)); taskStack.Push(new DrawTask('L', depth, dx, -dy)); taskStack.Push(new DrawTask('D', depth)); taskStack.Push(new DrawTask('L', depth, 2 * dx, 0)); taskStack.Push(new DrawTask('B', depth)); taskStack.Push(new DrawTask('L', depth, dx, dy)); taskStack.Push(new DrawTask('A', depth)); } }
Остальные процедуры реализуются аналогично:
static void drawB_NR(Graphics gr, int depth, ref float x, ref float y, float dx, float dy, Stack taskStack) { if (depth > 0) { --depth; taskStack.Push(new DrawTask('B', depth)); taskStack.Push(new DrawTask('L', depth, dx, dy)); taskStack.Push(new DrawTask('A', depth)); taskStack.Push(new DrawTask('L', depth, 0, 2 * dy)); taskStack.Push(new DrawTask('C', depth)); taskStack.Push(new DrawTask('L', depth, -dx, dy)); taskStack.Push(new DrawTask('B', depth)); } }
static void drawC_NR(Graphics gr, int depth, ref float x, ref float y, float dx, float dy, Stack taskStack) { if (depth > 0) { --depth; taskStack.Push(new DrawTask('C', depth)); taskStack.Push(new DrawTask('L', depth, -dx, dy)); taskStack.Push(new DrawTask('B', depth)); taskStack.Push(new DrawTask('L', depth, -2 * dx, 0)); taskStack.Push(new DrawTask('D', depth)); taskStack.Push(new DrawTask('L', depth, -dx, -dy)); taskStack.Push(new DrawTask('C', depth)); } }
static void drawD_NR(Graphics gr, int depth, ref float x, ref float y, float dx, float dy, Stack taskStack) { if (depth > 0) { --depth; taskStack.Push(new DrawTask('D', depth)); taskStack.Push(new DrawTask('L', depth, -dx, -dy)); taskStack.Push(new DrawTask('C', depth)); taskStack.Push(new DrawTask('L', depth, 0, -2 * dy)); taskStack.Push(new DrawTask('A', depth)); taskStack.Push(new DrawTask('L', depth, dx, -dy)); taskStack.Push(new DrawTask('D', depth)); } }

Анимация WPF при изменении свойства

Есть класс, представляющий игрока (привожу упрощенный вариант):
class Player : INotifyPropertyChanged { public string Name { get; }
int rank; public int Rank { get { return rank; } set { rank = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Rank")); } }
public event PropertyChangedEventHandler PropertyChanged;
public Player(string name) { Name = name; } }
Коллекция этих Players отображается, ну скажем, в ItemsControl:


Внешние силы меняют рейтинг игрока (не часто, не чаще 1 раза в несколько секунд).
Можно ли сделать средствами анимации WPF (не принципиально) так, чтобы при изменении рейтинга число в TextBox'е менялось плавно от текущего значения до нового, ну скажем, за 0.2 секунды?
Я могу, конечно, в сеттере запускать таймер, но это решение мне не нравится.


Ответ

Такой фичи из коробки нету, но её можно легко смастерить самостоятельно. Например, давайте заведём для этого attached property.
public static class AnimatableDoubleHelper { // Это attached property OriginalProperty. К нему мы будем привязывать свойство из VM, // и получать нотификацию об его изменении public static double GetOriginalProperty(DependencyObject obj) => (double)obj.GetValue(OriginalPropertyProperty); public static void SetOriginalProperty(DependencyObject obj, double value) => obj.SetValue(OriginalPropertyProperty, value); public static readonly DependencyProperty OriginalPropertyProperty = DependencyProperty.RegisterAttached( "OriginalProperty", typeof(double), typeof(AnimatableDoubleHelper), new PropertyMetadata(OnOriginalUpdated));
// это "производное" attached property, которое будет // анимированно "догонять" OriginalProperty public static double GetAnimatedProperty(DependencyObject obj) => (double)obj.GetValue(AnimatedPropertyProperty); public static void SetAnimatedProperty(DependencyObject obj, double value) => obj.SetValue(AnimatedPropertyProperty, value); public static readonly DependencyProperty AnimatedPropertyProperty = DependencyProperty.RegisterAttached( "AnimatedProperty", typeof(double), typeof(AnimatableDoubleHelper));
// это вызывается когда значение OriginalProperty меняется static void OnOriginalUpdated(DependencyObject o, DependencyPropertyChangedEventArgs e) { double newValue = (double)e.NewValue; // находим элемент, на котором меняется свойство FrameworkElement self = (FrameworkElement)o; DoubleAnimation animation = // создаём анимацию... new DoubleAnimation(newValue, new Duration(TimeSpan.FromSeconds(0.3))); // и запускаем её на AnimatedProperty self.BeginAnimation(AnimatedPropertyProperty, animation); } }
Как этим пользоваться? Очень просто. Пусть у нас был такой код:

Заменяем его на следующую конструкцию:

Получается вот что: