Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

№37 рассылки '.Net Собеседник':


Информационный Канал Subscribe.Ru

.Net Собеседник #37

Содержание
  1. От автора
  2. Обзор новостей
  3. Свой Bitmap Button на C#
  4. Время кода - Библиотека C# DateTime
  5. Форумы .Net на www.sql.ru

От автора

Здравствуйте, коллеги!

Вышел первый номер журнала "Алгоритм". Подписной индекс в каталоге прессы Украины 91132.
Подписаться можно также непосредственно через редакцию, как в бумажном, так и в электронном виде. Подробнее смотрите здесь.

Интервью с Александром Гладченко - ведущим рассылки "MS SQL Server- дело тонкое…"

    Здравствуйте, Александр! Спасибо за то, что согласились дать интервью. Расскажите немного о себе.
    Здравствуйте, Виталий! Я также хочу поприветствовать всех читателей первого выпуска Вашего нового журнала. Надеюсь, что ему будет сопутствовать успех, т.к. тематика и предме тная область, которую представляет это издание, очень актуальны и будут востребованы ещё очень долго. Мне 42 года, из которых десять лет моей жизни связаны с SQL Server. Начинал я с SQL Server 6.0. В начале, это был один из серверов, который мне нужно было администрировать, но он был одним из самых критически важных звеньев в технологической цепочке, т.е. мне приходилось уделять ему самое большое внимание. Внимания было столько, что, по-видимому, именно в те годы я и сроднился с этой СУБД, о чём не жалею и по сей день.
    (Полный текст статьи опубликован в журнале)

    Резервное копирование в репликации SQL Server

    Автор : А. Гладченко

    В этой статье рассматриваются требования к резервному копированию баз данных, задействованных в репликации моментальных снимков, репликации транзакций или репликации слиянием. Эти требования зависят от роли, которую сервер исполняет в репликации и от места, где в топологии репликации необходимо обеспечить восстановление тиражируемых данных. Чтобы восстановить участвующие в репликации данные, необходимо регулярно резервировать издателей, дистрибуторов и подписчиков. Статья основана на материалах электронной документации, поставляемой в дистрибутиве сервера баз данных SQL Server 2000 Books Online.
    (Полный текст статьи опубликован в журнале)

    Передача значений между веб-формами в ASP.NET

    Автор : Бипин Джоши; Дополнения : С.Топорков

    Веб-формы ASP.NET предлагают прекрасную событийно-управляемую программную модель для разработчиков. В целом она упрощает дизайн вашего приложения, но и сама по себе порождает некоторые проблемы. Например, в традиционном ASP можно было легко передавать значения от одной страницы к другой странице с использованием метода POST. Этим подходом нельзя воспользоваться в ASP.NET, если вы хотите использовать модель веб-форм (т.е. форма и элементы управления обрабатываются на стороне сервера). Однако есть несколько подходов, с помощью которых можно преодолеть эти ограничения. Например, значения можно передавать в строке запроса, используя сессионные переменные или с использованием метода Server.Transfer.
    (Полный текст статьи опубликован в журнале)

    Компоненты контроля ввода ASP .Net

    Автор : В. Чужа

    Идея контролировать ввод пользователя программного обеспечения (ПО), в зависимости от типа данных или по шаблону, наверняка возникла у разработчиков ПО вместе с первыми ошибками ввода и была реализована во многих программных продуктах. Например, в Turbo Vision фирмы Borland класс TinputLine имеет метод Valid, перекрыв который можно вести контроль правильности ввода данных. При работе с базами данных есть возможность задать так называемые constraints - ограничения на ввод на уровне, например, поля (столбца) или таблицы. Так, в СУБД MS SQL Server 2000 имеются такие типы ограничений на ввод на уровне поля (домена в терминах SQL Server), как DEFAULT - значение по умолчанию, CHECK - проверка значения на допустимость занесения в поле и REFERENTIAL - значение должно соответствовать одному из значений в другой таблице. Эти примеры являются разными способами реализации контроля ввода пользователя, служащие одной цели - повышению надёжности работы программного обеспечения. Наверняка именно поэтому не обошла вниманием эту идею и компания Microsoft в ASP.Net, представив нам 6 компонент для контроля ввода пользователя (ККВ). Разберём их подробнее.
    (Полный текст статьи опубликован в журнале)

    Технологии построения распределенных приложений в .NET. Часть 3. Пространство имен System.EnterpriceServices

    Автор : М.Сухов

    COM+, так же как и MSMQ, пришел к нам из века неуправляемых приложений. Раньше без таких компонентов не могло обойтись ни одно серьезное распределенное приложение. С появлением .NET картина несколько изменилось. COM+ никуда не ушел, зато появилась управляемая надстройка над ним, Serviced Components. И сейчас мы поговорим, как создавать компоненты на базе этой технологии и как использовать в программе поддержку COM+ сервисов.
    (Полный текст статьи опубликован в журнале)

    System.Object под микроскопом Remotesoft .Net Explorer'a

    Автор : В.Чужа

    Как вам должно быть известно, типы в C# бывают двух видов - ссылочные и структурные. Первые производятся от класса System.Object, вторые - от класса System.ValueType, который, в свою очередь, является также наследником класса System.Object. Различие переменных этих типов заключается в том, что переменные (или объекты) ссылочных типов размещаются в управляемой куче, в то время как переменные структурных типов (к которым относятся перечисления, структуры и все числовые типы данных) - в стеке. Общность их заключается в том, что все они являются наследниками класса System.Object, о котором мы и поговорим подробнее.
    (Полный текст статьи опубликован в журнале)

    Подсистема сопоставления записей в Хранилище Данных

    Автор : Д.Орлов

    Данная статья рассчитана на разработчиков информационных систем, специализирующихся в области обработки и хранения данных. В статье излагаются принципы проектирования и работы подсистемы сопоставления записей (далее - подсистема) хранилища данных, предназначенной для реальной интеграции данных, поступающих из различных информационных систем. Сопоставление записей (record linkage) - задача достаточно нетривиальная и, что немаловажно, мало описанная в русскоязычной технической литературе, так что данная статья является попыткой в какой-то мере восполнить этот пробел.
    (Полный текст статьи опубликован в журнале)

    Делаем отчёты в .Net своими руками

    Автор : В.Чужа

    Помню в конце 80-х годов, ещё во времена существования СССР, по телевидению показывали французский мультик-экранизацию романа Ж.Верна "Вокруг света за восемьдесят дней". Мультик был так себе, но запомнились высказывания одного из главных героев романа, Филиаса Фогга, одно из которых взято в роли эпиграфа к данной статье. Дело в том, что в случае необходимости создания отчётов на платформе .Net программисты часто пользуются либо встроенным генератором отчётов Crystal Reports компании Business Solutions, либо генераторами отчётов сторонних производителей. С ними то и дело возникают различные проблемы, в то время как сама платформа предоставляет прекрасные возможности по созданию отчётов в виде html-файлов с использованием Internet Explorer'a (да и вообще любого браузера) в качестве средства для их просмотра и печати.
    (Полный текст статьи опубликован в журнале)

На этом всё - желаю интересного чтения.

{К содержанию}

Обзор новостей

  1. DB Mail Director
    Бесплтная программа для рассылки почти одинаковых почтовых сообщений - например, поздравлений с Новым Годом. Автор - Юрий Бычковский. Описание здесь, скриншот здесь.
  2. Вышел FoxPro 9.0
    Microsoft выпустила версию 9.0 FoxPro, самостоятельной RDBMS и среду программирования. Эта версия содержит возможность создания веб-сервисов и возможность работы с XML, а также совместима с .NET. Также введены существенные улучшения в SQL, новые элементы управления для интерфейсов, фоновая компиляции в процессе разработки.
  3. Вышел .NET Memory Profiler 2.5
    .NET Memory Profiler – мощный инструмент для поиска утечек памяти и оптимизации её использования в ваших .NET программах. Основные особенности версии 2.5: .NET Memory Profiler API, отслеживание утилизации кучи, интеграция с Visual Studio.NET Integration, поддержка командной строки и .NET Framework 2.0
  4. Технический выпуск 9Rays.Net Instrumentation Model Kit
    9Rays.Net объявила о технологическом релизе уникального продукта в области инструментальных и графических компонент для .NET «Instrumentation Model Kit». Графический редактор позволяет создавать новые элементы управления, имеющие уникальный вид и функциональность – буквально двумя щелчками мыши. Можно создавать стандартные компоненты: Meters, Dials, Sliders, Gauges и специализированные: Manipulators, Scales и т.д.
  5. Вышел Aspose.Excel 2.9
    Aspose.Excel - компонент для создания отчётов и электронных таблиц в формате Excel, без использования самого Excel. В последнем выпуске добавлена поддержка импорта файлов SpreadsheetML files и т.п.
  6. Вышел Aspose.Excel.Web 1.0
    Aspose.Excel.Web – чистый .Net веб-компонент, который позволяет вам создавать интерактивные веб-страницы, которые выглядят как настолные приложения электронных таблиц; загружают данные прямо из таблиц Excel; и т.п.
  7. Начали просачиваться сведения о Internet Explorer 7
    Планы Microsoft относительно Internet Explorer 7 могут фактически оказаться более широкими, чем просто усовершенствование безопасности. Некоторые улучшения будут касаться введения закладок, поддержки PNG и улучшенной поддержки печати. Несомненно, будут присутствовать улучшения и в безопасности – такие как, предупреждение cross domain scripting и улучшенный интерфейс SSL. Также упоминается о наличии RSS Aggregator.

{К содержанию}

Статья номера

Свой Bitmap Button на C#

ЯЗЫК: C#
Автор статьи: JSimms

ПЕРЕВОД: Чужа В.Ф. ака hDrummer
КОД К СТАТЬЕ: Демонстрация - 38KB, Исходники - 14KB

Вступление

Причиной создания своей кнопки стало желание отображать разные картинки для каждого из состояний кнопки. Эти состояния бывают такими – кнопка отключена, в нормальном состоянии, над ней курсор мыши, кнопка нажата. В добавок к графике важно было иметь возможность написания текста на кнопке, а также иметь возможность контроля выравнивания кнопки относительно рисунка. Реализация похожа на стиль XP, кроме того имеет собственные особенности и отличия.

Использование кода

Код может быть разделен на три секции: данные, рендеринг и события.

  • Данные: приватные члены хранят состояние кнопки и (традиционно) значения свойств. Каждое свойство описано ниже, в таблице свойств.
  • Рендеринг (отрисовка): осуществляется несколькими методами; однако метод OnPaint является основным, вызывающим другие методы для этой цели.
  • События: несколько методов перегружены с целью обработки событий и управления состоянием кнопки. Вот эти события OnMouseDown, OnMouseUp, OnMouseLeave, OnMouseMove, OnEnabledChanged, OnLostFocus.

При просмотре кода все эти секции могут быть легко найдены, поскольку они разбиты на области с помощью ключевого слова #region.

Данные:

Для начала рассмотрим свойства кнопки.

BackColor Цвет фона кнопки
BorderColor Цвет линии толщиной в один пиксель, окружающей кнопку
Font Шрифт, используемый при рендеринге текста
ForeColor Цвет текста кнопки
ImageAlign Выравнивание рисунка
ImageBorderColor Если ImageBorderEnabled = true, то это свойство содержит цвет границы отрендереной картинки. В добавок, свойство StretchImage должно быть = false.
ImageBorderEnabled true, если надо отрисовывать границу картинки, иначе false
ImageDropShadow true, если надо отрисоввывать тень вокруг границы картинки
ImageFocused Картинка, которую нужно отрисовывать, если кнопка в фокусе и нормальном состоянии
ImageInactive Картинка, которую нужно отрисовывать, если кнопка отключена (disabled). Заметьте, если картинка не указана, используется ч/б версия нормальной картинки
ImageMouseOver Картинка, которую нужно отрисовывать, если курсор мыши находится над кнопкой, но кнопка не нажата
ImageNormal Картинка, которую нужно отрисовывать, если кнопка в нормальном состоянии
ImagePressed Картинка, которую нужно отрисовывать, если кнопка нажата
InnerBorderColor Цвет для внутренней границы кнопки в нормальном состоянии
InnerBorderColor_Focus Цвет для внутренней границы кнопки в фокусе
InnerBorderColor_MouseOver Цвет для внутренней границы кнопки при курсоре мыши над кнопкой
OffsetPressedContent Если свойство установлено в true, а кнопка нажата, то содержимое кнопки сдвигается.
Padding В этом свойстве хранится число пикселей между содержимым кнопки – картинкой, текстом и границей.
StretchImage Если=true, то картинка в кнопке растягивается.
Text Текст в кнопке
TextAlignment Выравнивание текста кнопки
TextDropShadow Если=true, текст отбрасывает тень

Все свойства находятся в категории "Отображение" (appearance) на странице свойств.

Отрисовка:

Отрисовка выполняется методом OnPaint. Он, в свою очередь, вызывает несколько методов для отрисовки разных частей кнопки.

  • CreateRegion: создаёт прозрачную границу кнопки
  • paint_Background: отрисовка фона кнопки.
  • paint_Text: отрисовка текста и тени.
  • paint_Border: отрисовка однопиксельной границы кнопки.
  • paint_InnerBorder: отрисовка двухпиксельной внутренней рамки кнопки.
  • paint_FocusBorder: отрисовка однопиксельной пунктирной рамки в кнопке.
Теперь подробнее рассмотрим код.

//
// Этот метод отрисовывает кнопку.
//

//
protected override void OnPaint(PaintEventArgs e)
{
CreateRegion(0);
paint_Background(e);
paint_Text(e);
paint_Image(e);
paint_Border(e);
paint_InnerBorder(e);
paint_FocusBorder(e);}

Отрисовка фона достаточно интересна. Использованный подход позволяет использовать градиентную интерполяцию фона для множества цветов (подразумевается, число больше чем два). Сначала объект, подвергающийся смешению, должен быть проинициализирован массивом цветов и позицией интерполяции. Затем, как обычно, создаётся градиентная кисть. И, наконец, смешиваемый объект привязывается к кисти. Это осуществляется установкой свойства кисти InterpolationColors .
Далее следует пример интерполяции нескольких цветов:

Color[] ColorArray = new Color[]{
   System.Drawing.Color.White,
   System.Drawing.Color.Yellow,
   System.Drawing.Color.Blue,
   System.Drawing.Color.Green,               
   System.Drawing.Color.Red,
   System.Drawing.Color.Black};
float[] PositionArray  = new float[]{0.0f,.15f,.40f,.65f,.80f,1.0f};
//
// создаём переменную смешения для интерполяции цветов
//
System.Drawing.Drawing2D.ColorBlend blend = new System.Drawing.Drawing2D.ColorBlend();
blend.Colors    = ColorArray;
blend.Positions = PositionArray;
//
// создаём вертикальную градиентнуб кисть
//
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(rect, this.BackColor,Blend(this.BackColor,this.BackColor,10),
System.Drawing.Drawing2D.LinearGradientMode.Vertical);
brush.InterpolationColors = blend;
//
// заполняем прямоугольник
//
g.FillRectangle(brush, rect);
//
// освобождаем ресурсы
//
brush.Dispose();

Для отрисовки текста я использовал метод System.Drawing.DrawString. Хитрость заключается в том, чтобы определить, где отрисовать текст. По причине большого количества кода, эта функциональность была размещена в функции-помощники, чтобы не загромождать метод paint_Text. Также этот метод реализует функциональность по отбрасыванию тени текстом. Для этого просто используется отрисовка кистями с альфа-компонентами, а текст рисуем как обычно.

//
// отрисовка тени
//
if(TextDropShadow)
{
System.Drawing.Brush TransparentBrush0 = new System.Drawing.SolidBrush( System.Drawing.Color.FromArgb(50, System.Drawing.Color.Black  ) ) ;
System.Drawing.Brush TransparentBrush1 = new System.Drawing.SolidBrush( System.Drawing.Color.FromArgb(20, System.Drawing.Color.Black  ) ) ;

e.Graphics.DrawString(this.Text,this.Font, TransparentBrush0,pt.X,pt.Y+1);
e.Graphics.DrawString(this.Text,this.Font, TransparentBrush0,pt.X+1,pt.Y);
e.Graphics.DrawString(this.Text,this.Font, TransparentBrush1,pt.X+1,pt.Y+1);
e.Graphics.DrawString(this.Text,this.Font, TransparentBrush1,pt.X,pt.Y+2);
e.Graphics.DrawString(this.Text,this.Font, TransparentBrush1,pt.X+2,pt.Y);
TransparentBrush0.Dispose();
TransparentBrush1.Dispose();
}

Отрисовка картинки – скорее прямолинейный и простой процесс. Однако, я столкнулся с некоторыми трудностями при использовании нижеприведенного метода. Он прекрасно работал с картинкой, созданной в редакторе ресурсов, но не работал с 24-битной картинкой, созданной в графическом редакторе. Пришлось вызывать другой метод DrawImage. Он немного медленне, но пока я не пойму в чём проблема, именно он будет работать.

// не работает
g.DrawImage(image,rect.Left,rect.Top)
// текущий подход
g.DrawImage(image,rect, 0, 0 ,image.Width,image.Height, GraphicsUnit.Pixel);

Раскраска границ интерполированными цветами не вызвала трудностей. Мы проделываем теже шаги, что и в случае с градиентной кистью. Градиентная кисть передаётся как параметр при создании объекта-карандаша:

....
//
// создаём кисть и карандаши
//
System.Drawing.Drawing2D.LinearGradientBrush brush
new System.Drawing.Drawing2D.LinearGradientBrush(rect,  
this.BackColor,Blend(this.BackColor,this.BackColor,10), 
System.Drawing.Drawing2D.LinearGradientMode.Vertical);
brush.InterpolationColors = blend;
System.Drawing.Pen pen0 = new System.Drawing.Pen(brush,1);
//
// рисуем линию 0
//
g.DrawLine(pen0 , point_0,point_1);

События:

Мы уже кратко описали отрисовку картинки. Следующий важный аспект – отслеживание и обработка ввода. Был использован подход с перекрытием методов базового класса кнопки. Эти методы затем изменяют свойства кнопки. Как только состояние изменилось, вызывается механизм OnPaint() для обновления картинки. Ниже перечислены методы событий и их назначение:

Методы событий

Назначение

OnMouseDown Устанавливает BtnState в Pushed и CapturingMouse в true
OnMouseUp Устанавливает BtnState в Normal и CapturingMouse в false
OnMouseLeave Устанавливает BtnState в normal, если CapturingMouse = true
OnMouseMove Если CapturingMouse = true и координаты курсора мыши внутри кнопки, то устанавливает BtnState в Pushed, иначе устанавливает BtnState в Normal. Если CapturingMouse = false, устанавливает BtnState в MouseOver
OnEnabledChanged Кнопка становится или включенной или отключенной. Если включается, то устанавливает BtnState в Normal, иначе - устанавливает BtnState в Inactive
OnLostFocus Устанавливает btnState в Normal

Ниже приведен код, касающийся событий. События обычно не содержат много кода. Ещё одна изюминка, про которую нужно сказать – свойство Capture элемента управления. Устанавливая его в true, кнопка не тереят фокус, если курсор мыши выходит за границы кнопки. Это важно, поскольку если кнопка мыши нажата, а пользователь уводит указатель за границы кнопки, то состояние кнопки должно соответственно измениться. Если свойство Capture не установлено, то кнопка прекращает отлавливать ввод, когда указатель выходит за её границы.

//
// Событие Mouse Down:
// установка BtnState в Pushed и CapturingMouse в true
//

//
protected override void OnMouseDown(MouseEventArgs e)
{
  base.OnMouseDown (e);
  this.Capture = true;
  this.CapturingMouse = true;
  btnState = BtnState.Pushed;
  this.Invalidate();
}

Послесловие...

Это первая инкарнация кнопки, весь код находится в одном файле, BitmapButton.cs. Позже, если позволит время и кнопка вызовет интерес, можно добавить использование интерфейсов – для улучшения функциональности и расширяемости кода. Можно добавить поддержку тем и доступ к ним из xml. Кэширование картинок также видится вполне интересной целью. Я жду замечаний и надеюсь, что кнопка вам пригодится или, как минимум, даст вам идеи для создания ваших собственных элементов управления.

{К содержанию}

Время кода

Библиотека C# DateTime

ЯЗЫК: C#
Автор статьи: Michael Ceranski

ПЕРЕВОД: Чужа В.Ф. ака hDrummer
КОД К СТАТЬЕ: DateUtilitiesSource.zip

Я недавно перешёл с Delphi на C# и заметил, что некоторые функции, которые я ранее часто использовал, тут просто отсутствуют. Именно поэтому я и написал их. Надеюсь, что кому-то они сэкономят время так же, как и мне.

public enum Quarters
{
    First = 1,
    Second = 2,
    Third = 3,
    Fourth = 4
}        

public class DateUtilities
{
    #region Quarters

    public static DateTime GetStartOfQuarter( int Year, Quarters Quarter )
    {
        if( Quarter == Quarters.First )
// 1st Quarter = January 1 to March 31
            return new DateTime( Year, 1, 1, 0, 0, 0, 0 );
        else if( Quarter == Quarters.Second )
// 2nd Quarter = April 1 to June 30
            return new DateTime( Year, 4, 1, 0, 0, 0, 0 );
        else if( Quarter == Quarters.Third )
// 3rd Quarter = July 1 to September 30
            return new DateTime( Year, 7, 1, 0, 0, 0, 0 );
        else
// 4th Quarter = October 1 to December 31
            return new DateTime( Year, 10, 1, 0, 0, 0, 0 );
        
    }

    public static DateTime GetEndOfQuarter( int Year, Quarters Quarter )
    {
        if( Quarter == Quarters.First )
// 1st Quarter = January 1 to March 31
            return new DateTime( Year, 3, 
                DateTime.DaysInMonth( Year, 3 ), 23, 59, 59, 999 );
        else if( Quarter == Quarters.Second )
// 2nd Quarter = April 1 to June 30
            return new DateTime( Year, 6, 
                DateTime.DaysInMonth( Year, 6 ), 23, 59, 59, 999 );
        else if( Quarter == Quarters.Third )
// 3rd Quarter = July 1 to September 30
            return new DateTime( Year, 9, 
                DateTime.DaysInMonth( Year, 9 ), 23, 59, 59, 999 );
        else
// 4th Quarter = October 1 to December 31
            return new DateTime( Year, 12, 
                DateTime.DaysInMonth( Year, 12 ), 23, 59, 59, 999 );
    }

    public static Quarters GetQuarter( int Month )
    {
        if( Month <= 3 )
// 1st Quarter = January 1 to March 31
            return Quarters.First;
        else if( ( Month >= 4 ) && ( Month <= 6 ) )
// 2nd Quarter = April 1 to June 30
            return Quarters.Second;
        else if( ( Month >= 7 ) && ( Month <= 9 ) )
// 3rd Quarter = July 1 to September 30
            return Quarters.Third;
        else 
// 4th Quarter = October 1 to December 31
            return Quarters.Fourth;
    }

    public static DateTime GetEndOfLastQuarter()
    {            
        if( DateTime.Now.Month <= 3 )
//go to last quarter of previous year
            return GetEndOfQuarter( DateTime.Now.Year - 1, 
                12, GetQuarter( 12 ));
        else
//return last quarter of current year
            return GetEndOfQuarter( DateTime.Now.Year, 
                DateTime.Now.Month, GetQuarter( DateTime.Now.Month));
    }

    public static DateTime GetStartOfLastQuarter()
    {
        if( DateTime.Now.Month <= 3 )
//go to last quarter of previous year
            return GetStartOfQuarter( DateTime.Now.Year - 1, 12, 
                GetQuarter( 12 ));
        else
//return last quarter of current year
            return GetStartOfQuarter( DateTime.Now.Year, 
                DateTime.Now.Month, GetQuarter( DateTime.Now.Month));
    }

    public static DateTime GetStartOfCurrentQuarter()
    {
        return GetStartOfQuarter( DateTime.Now.Year, 
            DateTime.Now.Month, GetQuarter( DateTime.Now.Month ));
    }

    public static DateTime GetEndOfCurrentQuarter()
    {
        return GetEndOfQuarter( DateTime.Now.Year, 
            DateTime.Now.Month, GetQuarter( DateTime.Now.Month ));
    }
    #endregion

    #region Weeks
    public static DateTime GetStartOfLastWeek()
    {
        int DaysToSubtract = (int)DateTime.Now.DayOfWeek + 7;
        DateTime dt = DateTime.Now.Subtract( 
            System.TimeSpan.FromDays( DaysToSubtract ) );
        return new DateTime( dt.Year, dt.Month, dt.Day, 0, 0, 0, 0 );
    }

    public static DateTime GetEndOfLastWeek()
    {
        DateTime dt = GetStartOfLastWeek().AddDays(6);
        return new DateTime( dt.Year, dt.Month, dt.Day, 23, 59, 
            59, 999 );
    }

    public static DateTime GetStartOfCurrentWeek()
    {
        int DaysToSubtract = (int)DateTime.Now.DayOfWeek ;
        DateTime dt = DateTime.Now.Subtract( 
            System.TimeSpan.FromDays( DaysToSubtract ) );
        return new DateTime( dt.Year, dt.Month, dt.Day, 0, 0, 0, 0 );
    }

    public static DateTime GetEndOfCurrentWeek()
    {
        DateTime dt = GetStartOfCurrentWeek().AddDays(6);
        return new DateTime( dt.Year, dt.Month, dt.Day, 23, 59, 59, 
            999 );
    }
    #endregion

    #region Months

    public static DateTime GetStartOfMonth( int Month, int Year )
    {
        return new DateTime( Year, Month, 1, 0, 0, 0, 0 );
    }

    public static DateTime GetEndOfMonth( int Month, int Year )
    {
        return new DateTime( Year, Month, 
            DateTime.DaysInMonth( Year, Month ), 23, 59, 59, 999 );
    }

    public static DateTime GetStartOfLastMonth()
    {
        if( DateTime.Now.Month == 1 )
            return GetStartOfMonth( 12, DateTime.Now.Year - 1);
        else
            return GetStartOfMonth( DateTime.Now.Month -1, 
                DateTime.Now.Year );            
    }

    public static DateTime GetEndOfLastMonth()
    {
        if( DateTime.Now.Month == 1 )
            return GetEndOfMonth( 12, DateTime.Now.Year - 1);
        else
            return GetEndOfMonth( DateTime.Now.Month -1, 
                DateTime.Now.Year );
    }

    public static DateTime GetStartOfCurrentMonth()
    {
        return GetStartOfMonth( DateTime.Now.Month, 
            DateTime.Now.Year );
    }

    public static DateTime GetEndOfCurrentMonth()
    {
        return GetEndOfMonth( DateTime.Now.Month, 
            DateTime.Now.Year );
    }
    #endregion
    ...окончание библиотеки (region Year) см. по ссылке...
  }

Вот и всё.


{К содержанию}

Форумы .Net - вопросы оставшиеся без ответа

Про System.Web.Mail
Отследить событие
Пересоздание объекта

На этом тридцать седьмой выпуск .Net Собеседника закончен.
До следующего номера.



Чужа Виталий Ф. aka hDrummer, MCAD, MCDBA, MCP
hdrummer@sql.ru - жду ваши предложения и замечания.



http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.dotnetgrains
Отписаться

В избранное