Язык и региональные стандарты

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Adept
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 21.02.2005 (Пн) 7:59
Откуда: Питер

Язык и региональные стандарты

Сообщение Adept » 27.09.2009 (Вс) 20:35

Текущая дата получается в формате, соответствующем выставленному в винде языку и региональным стандартам.
Как перевести ее в формат "en-US" (English USA)?
В msdn'e нашел только реализацию на .NET через класс CultureInfo, а для vb6 найти не удалось.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Язык и региональные стандарты

Сообщение alibek » 27.09.2009 (Вс) 22:50

GetLocaleInfo тебе поможет, укажи только нужный LCID.
Lasciate ogni speranza, voi ch'entrate.

Adept
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 21.02.2005 (Пн) 7:59
Откуда: Питер

Re: Язык и региональные стандарты

Сообщение Adept » 28.09.2009 (Пн) 3:07

Спасибо, почитал :)
Как сменить языковой стандарт целиком не нашел, поэтому пытался менять отдельные параметры текущего, предварительно сохранив их для последующего восстановления.
Код: Выделить всё
Locale = GetUserDefaultLCID()
iRet = SetLocaleInfo(Locale, LOCALE_SSHORTDATE, DateFormat)  ' эта строка работает отлично
iRet = SetLocaleInfo(Locale, LOCALE_SABBREVMONTHNAME9, "Sep") ' а вот эта выдает еррор

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

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: Язык и региональные стандарты

Сообщение Viper » 28.09.2009 (Пн) 5:45

Возможно размер строки в третьем параметре маловат.
Весь мир матрица, а мы в нем потоки байтов!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Язык и региональные стандарты

Сообщение alibek » 28.09.2009 (Пн) 8:07

Зачем их вообще менять?
Посмотри в справочнике нужный LCID и задавай его константой.
Lasciate ogni speranza, voi ch'entrate.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Язык и региональные стандарты

Сообщение Andrey Fedorov » 28.09.2009 (Пн) 8:11

А для чего, собственно, нужна дата в амер-формате?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Adept
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 21.02.2005 (Пн) 7:59
Откуда: Питер

Re: Язык и региональные стандарты

Сообщение Adept » 28.09.2009 (Пн) 11:40

Viper писал(а):Возможно размер строки в третьем параметре маловат.

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

alibek писал(а):Зачем их вообще менять?
Посмотри в справочнике нужный LCID и задавай его константой.

LCID смотрел и здесь, и вручную, выставив нужный язык и посмотрев его ид через GetUserDefaultLCID.
Проблема в том, что функция SetLocaleInfo, судя по описанию, меняет только определенный параметр, зависящий от указанной константы (отображение даты, времени, разделители и т.д.), а как поменять весь языковой стандарт разом, как я уже писал, не нашел.

Andrey Fedorov писал(а):А для чего, собственно, нужна дата в амер-формате?

Впоследствии текущую дату надо сравнивать с датой шаблона "mmm dd yyyy", причем аббревиатура названия месяца на английском языке.
Но нельзя гарантировать, что на этом компьютере стоит именно англоязычный языковой стандарт.

Adept
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 21.02.2005 (Пн) 7:59
Откуда: Питер

Re: Язык и региональные стандарты

Сообщение Adept » 30.09.2009 (Ср) 13:42

Вот, нашел еще статью по смене локали.
http://www.microsoft.com/globaldev/drintl/columns/009/default.mspx#EHF
User Locale: Or "Standards and formats" in Windows XP. This per user variable defines user's preferences for formatting locale sensitive data (date, time, currency ...). Your application should be using that setting to display formatted data. Use GetUserDefaultLCID to retrieve that value. No API available to set this locale (by design).
• In Windows 2000, users can change this in the "Your locale (location)" option in the "Settings for the current user" field of the "General" tab of the "Regional Options" Control Panel applet (can be set on the fly).
• In Windows XP, users can change it thru the Region Options tab of the Regional and Language Options applet (can be set on the fly).

Насколько я понял, это то, что мне нужно, но апи для смены UserLocale нет.

Тогда остается вопрос, почему у меня смена формата выводимой Short Date у текущей локали работает, а смена аббревиатуры месяца не хочет.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Язык и региональные стандарты

Сообщение Vi » 01.10.2009 (Чт) 9:43

Есть еще вариант, описан в Studio\VB98\Wizards\PDWizard\Setup1\SETUP1.BAS
Код: Выделить всё
Public Declare Function VariantChangeTypeEx Lib "oleaut32.dll" (ByVal pvArgDest As Long, _
     ByVal pvArgSrc As Long, ByVal LCID As Long, ByVal wFlags As Integer, ByVal VarType As Integer) As Long
'...
'-----------------------------------------------------------
' SUB: ParseDateTime
'
' Same as CDate with a string argument, except that it
' ignores the current localization settings.  This is
' important because SETUP.LST always uses the same
' format for dates.
'
' IN: [strDate] - string representing the date in
'                 the format mm/dd/yy or mm/dd/yyyy
' OUT: The date which strDate represents
'-----------------------------------------------------------
'
Private Function ParseDateTime(ByVal strDateTime As String) As Date
    Dim Var As Variant

    Var = strDateTime
    If 0 = VariantChangeTypeEx(VarPtr(Var), VarPtr(Var), &H409, 0, vbDate) Then
        ParseDateTime = Var
    Else
        'Raise same error as CDate
        Err.Raise 13
    End If
End Function
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Gogic
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 24.08.2008 (Вс) 13:19

Re: Язык и региональные стандарты

Сообщение Gogic » 01.10.2009 (Чт) 10:10

Код: Выделить всё
Locale = GetUserDefaultLCID()
iRet = SetLocaleInfo(Locale, LOCALE_SSHORTDATE, DateFormat)  ' эта строка работает отлично
iRet = SetLocaleInfo(Locale, LOCALE_SABBREVMONTHNAME9, "Sep") ' а вот эта выдает еррор


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


Константы точно объявлены?

Код: Выделить всё
Const LOCALE_SSHORTDATE As Long = &H1F
Const LOCALE_SABBREVMONTHNAME9 As Long = &H4C

Adept
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 21.02.2005 (Пн) 7:59
Откуда: Питер

Re: Язык и региональные стандарты

Сообщение Adept » 01.10.2009 (Чт) 13:06

Gogic писал(а):Константы точно объявлены?

Да
Vi писал(а):Есть еще вариант, описан в Studio\VB98\Wizards\PDWizard\Setup1\SETUP1.BAS

Там третьим параметром задается LCID и если он для английского языка, тогда функция не может разобрать строку "сен 09 2009", а если для русского, тогда ошибка со строкой "sep 09 2009".

А вообще, я просто ошибся в логике действий)
Какой бы региональный стандарт ни стоял, достаточно сравнить три символа текущей даты в формате "mmm" либо с GetLocaleInfo(CurrentLocale, LOCALE_SABBREVMONTHNAME#, ...) либо со встроенной в VB функцией MonthName и заменить на английскую аббревиатуру.
Код: Выделить всё
Select Case Format$(Date, "mmm")
Case MonthName(1, True)
    dateEng = "jan" & Format$(Date, " dd yyyy")
Case MonthName(2, True)
    dateEng = "feb" & Format$(Date, " dd yyyy")
Case MonthName(3, True)
    dateEng = "mar" & Format$(Date, " dd yyyy")
Case MonthName(4, True)
    dateEng = "apr" & Format$(Date, " dd yyyy")
Case MonthName(5, True)
    dateEng = "may" & Format$(Date, " dd yyyy")
Case MonthName(6, True)
    dateEng = "jun" & Format$(Date, " dd yyyy")
Case MonthName(7, True)
    dateEng = "jul" & Format$(Date, " dd yyyy")
Case MonthName(8, True)
    dateEng = "aug" & Format$(Date, " dd yyyy")
Case MonthName(9, True)
    dateEng = "sep" & Format$(Date, " dd yyyy")
Case MonthName(10, True)
    dateEng = "oct" & Format$(Date, " dd yyyy")
Case MonthName(11, True)
    dateEng = "nov" & Format$(Date, " dd yyyy")
Case MonthName(12, True)
    dateEng = "dec" & Format$(Date, " dd yyyy")
End Select

В результате в dateEng всегда дата в нужном формате, независимо от регионального стандарта.
Но спасибо за наводящие вопросы :)

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Язык и региональные стандарты

Сообщение Andrey Fedorov » 02.10.2009 (Пт) 23:09

Adept писал(а):В результате в dateEng всегда дата в нужном формате, независимо от регионального стандарта.
Но спасибо за наводящие вопросы :)


Слишком много кода. Пиши короче:

Код: Выделить всё
Debug.Print Mid$("janfebmaraprmayjunjulaugsepoctnovdec",3 * Month(Date)-2,3) & Format$(Date, " dd yyyy")
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Язык и региональные стандарты

Сообщение alibek » 02.10.2009 (Пт) 23:28

Лучше все-таки Choose, а не трики.
Потом этот код еще сопровождать надо будет.
Lasciate ogni speranza, voi ch'entrate.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Язык и региональные стандарты

Сообщение Andrey Fedorov » 02.10.2009 (Пт) 23:45

Вариант с API:

Код: Выделить всё
Option Explicit

Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long

Public Sub Main()
    Debug.Print GetEngStr(Date)
End Sub

Private Function GetEngStr(d As Date) As String
    Dim Buffer As String * 20, i As Long
   
    i = GetLocaleInfo(&H409, &H43 + Month(d), Buffer, 20)
    GetEngStr = LCase$(Left$(Buffer, i - 1)) & Format$(d, " dd yyyy")
End Function
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Mail.ru [бот] и гости: 53

    TopList