I've been using WMI a lot to get information from servers and I've been getting good results
(generic though like processor state, hdd, logged on users, process lists etc )
Now I have a specific task to query some specific data from an Exchange Server 2010
Data like the one you might get from the performance monitor and health check
like Active Mailbox Delivery Queue, send queue size, receive queue size, SMTP Current Connections and the list goes on and on.
Now I've been doing some research and i've found some articles and found that
this class is supposed to have the data I need : root\MicrosoftExchangeV2
I'm having a hard time coding this and I've found some vb examples that I tried to convert in perl modules but nothing seem to work.
Any start up example is appreciated
ps: on the exchange server wmi seems to be not accesable from remote (so i run this locally)
#!/usr/bin/perl
use Win32::OLE('in');
use constant bFlagReturnImmediately => 0x10;
use constant bFlagForwardOnly => 0x20;
#use warnings;
use Win32::OLE::Enum;
my $comp = ".";
my $oWMIService_ = Win32::OLE->GetObject( "winmgmts:impersonationLevel=impersonate}!\\\\$comp\\ROOT\\MicrosoftExchangeV2") or die "problem";
my $colItems_ = $oWMIService_->ExecQuery ( "Select * from Exchange_Link", "WQL", bFlagReturnImmediately | bFlagForwardOnly);
foreach my $objItem_ (in $colItems_){
print $objItem_->{StateRemote};
}
After digging deep into microsoft's documentation and monitoring wmi i managed to find the specific performance counters as below:
ExchangePop3_MSExchangePop3ConnectionsCurrent => 0
TransportQueues_MSExchangeTransportQueuesLargestDeliveryQueueLength => 0
TransportQueues_MSExchangeTransportQueuesRetryMailboxDeliveryQueueLength => 0
IS_MSExchangeISMailboxActiveClientLogons => 193
TransportQueues_MSExchangeTransportQueuesUnreachableQueueLength => 0
TransportSmtpSend_MSExchangeTransportSmtpSendMessagesSentPerSec => 0
TransportSMTPReceive_MSExchangeTransportSMTPReceiveConnectionsTotal => 190
TransportQueues_MSExchangeTransportQueuesMessagesQueuedForDelivery => 0
TransportQueues_MSExchangeTransportQueuesRetryNonSmtpDeliveryQueueLength => 0
Imap4_MSExchangeImap4CurrentConnections => 0
ActiveSync_MSExchangeActiveSyncRequestsPersec => 0
TransportQueues_MSExchangeTransportQueuesActiveMailboxDeliveryQueueLength => 0
TransportQueues_MSExchangeTransportQueuesSubmissionQueueLength => 0
TransportQueues_MSExchangeTransportQueuesActiveRemoteDeliveryQueueLength => 0
TransportSmtpSend_MSExchangeTransportSmtpSendConnectionsTotal => 92
MailSubmission_MSExchangeMailSubmissionFailedSubmissionsPerSecond => 0
MSExchangeISActiveUserCount => 0
TransportQueues_MSExchangeTransportQueuesActiveNonSmtpDeliveryQueueLength => 0
TransportQueues_MSExchangeTransportQueuesRetryRemoteDeliveryQueueLength => 0
TransportQueues_MSExchangeTransportQueuesAggregateDeliveryQueueLengthAllQueues => 0
OWA_MSExchangeOWAAverageResponseTime => 120
ActiveConnectionCount => 101
I hope somebody might get these useful for any monitoring tool they might be writing
to monitor any busy exchange server
Related
I started the following code to handle a Bosch BME280 sensor with a Nucleo-F446ZE and a Nucleo-F411RE boards.
with STM32.Device; use STM32.Device;
with STM32.GPIO; use STM32.GPIO;
with STM32; use STM32;
with STM32.I2C;
with HAL.I2C; use HAL.I2C;
use HAL;
procedure Simple_I2C_Demo is
-- I2C Bus selected
Selected_I2C_Port : constant access STM32.I2C.I2C_Port := I2C_1'Access;
Selected_I2C_Port_AF : constant GPIO_Alternate_Function := GPIO_AF_I2C1_4;
Selected_I2C_Clock_Pin : GPIO_Point renames PB8;
Selected_I2C_Data_Pin : GPIO_Point renames PB9;
Port : constant HAL.I2C.Any_I2C_Port := Selected_I2C_Port;
-- Shift one because of 7-bit addressing
I2C_Address : constant HAL.I2C.I2C_Address := 16#76# * 2;
procedure SetupHardware is
GPIO_Conf_AF : GPIO_Port_Configuration (Mode_AF);
Selected_Clock_Speed : constant := 10_000;
begin
Enable_Clock (Selected_I2C_Clock_Pin);
Enable_Clock (Selected_I2C_Data_Pin);
Enable_Clock (Selected_I2C_Port.all);
STM32.Device.Reset (Selected_I2C_Port.all);
Configure_Alternate_Function (Selected_I2C_Clock_Pin, Selected_I2C_Port_AF);
Configure_Alternate_Function (Selected_I2C_Data_Pin, Selected_I2C_Port_AF);
GPIO_Conf_AF.AF_Speed := Speed_100MHz;
GPIO_Conf_AF.AF_Output_Type := Open_Drain;
GPIO_Conf_AF.Resistors := Pull_Up;
Configure_IO (Selected_I2C_Clock_Pin, GPIO_Conf_AF);
Configure_IO (Selected_I2C_Data_Pin, GPIO_Conf_AF);
STM32.I2C.Configure
(Selected_I2C_Port.all,
(Clock_Speed => Selected_Clock_Speed,
Addressing_Mode => STM32.I2C.Addressing_Mode_7bit,
Own_Address => 16#00#, others => <>));
STM32.I2C.Set_State (Selected_I2C_Port.all, Enabled => True);
end SetupHardware;
ID : HAL.I2C.I2C_Data (1 .. 1);
Status : HAL.I2C.I2C_Status;
begin
SetupHardware;
HAL.I2C.Mem_Read (This => Port.all,
Addr => I2C_Address,
Mem_Addr => 16#D0#,
Mem_Addr_Size => HAL.I2C.Memory_Size_8b,
Data => ID,
Status => Status,
Timeout => 15000);
if Status /= Ok then
raise Program_Error with "I2C read error:" & Status'Img;
end if;
end Simple_I2C_Demo;
In this simple example, I always get an error status at the end of reading. In the context of a more complete code, I always get a Busy status after waiting 15secs.
I really don't see what is going on as my code is largely inspired from the code I found on Github for a I2C sensor.
Maybe I forgot a specific code for I2C init but as I'm not an expert, I prefer to ask to experts :)
Finally found what was wrong. After testing with C using STM HAL and investigating the Ada configuration code, I found that a line was missing:
GPIO_Conf_AF.AF_Speed := Speed_100MHz;
GPIO_Conf_AF.AF_Output_Type := Open_Drain;
GPIO_Conf_AF.Resistors := Pull_Up;
-- Missing configuration part of the record
GPIO_Conf_AF.AF := Selected_I2C_Port_AF;
-- That should be present even though there was a call to configure
-- each pin few lines above
Configure_IO (Selected_I2C_Clock_Pin, GPIO_Conf_AF);
Configure_IO (Selected_I2C_Data_Pin, GPIO_Conf_AF);
Using Configure_IO after Configure_Alternate_Function crushes the configuration and, as there was a part of the record which was left uninitialized, the GPIO were incorrectly configured.
To be more precise, after looking at the code inside the GPIO handling, Configure_IO calls Configure_Alternate_Function using the AF part of the GPIO_Port_Configuration record. In my case, it was resetting it.
With the missing line, the code now runs correctly with Mem_Read and Master_Transmit/Master_Receive.
A big thanks to ralf htp for advising me to dive into the generated C code.
No, between HAL_I2C_Mem_Read and the HAL_I2C_Master_Transmit, wait, HAL_I2C_Master_Receive procedure is only a nuance cf How do I use the STM32CUBEF4 HAL library to read out the sensor data with i2c? . If you know what size of data you want to receive you can use the HAL_I2C_Master_Transmit, wait, HAL_I2C_Master_Receive procedure.
A C++ HAL I2C example is in https://letanphuc.net/2017/05/stm32f0-i2c-tutorial-7/
//Trigger Temperature measurement
buffer[0]=0x00;
HAL_I2C_Master_Transmit(&hi2c1,0x40<<1,buffer,1,100);
HAL_Delay(20);
HAL_I2C_Master_Receive(&hi2c1,0x40<<1,buffer,2,100);
//buffer[0] : MSB data
//buffer[1] : LSB data
rawT = buffer[0]<<8 | buffer[1]; //combine 2 8-bit into 1 16bit
Temperature = ((float)rawT/65536)*165.0 -40.0;
//Trigger Humidity measurement buffer[0]=0x01;
HAL_I2C_Master_Transmit(&hi2c1,0x40<<1,buffer,1,100);
HAL_Delay(20);
HAL_I2C_Master_Receive(&hi2c1,0x40<<1,buffer,2,100);
//buffer[0] : MSB data
//buffer[1] : LSB data
rawH = buffer[0]<<8 | buffer[1]; //combine 2 8-bit into 1 16bit
Humidity = ((float)rawH/65536)*100.0; HAL_Delay(100); }
Note that it uses HAL_I2C_Master_Transmit, waits 20 ms until the slave puts the data on the bus and then receives it with HAL_I2C_Master_Receive. This code is working, i tested it myself.
Possibly the problem is that the BME280 supports single byte reads and multi-byte reads (until it sends a NOACK and stop). HAL_I2C_Mem_Read waits for the ACK or stop but for some reasons it does not get it what causes the Busy and then Timeout behavior, cf page 33 of the datasheet http://www.embeddedadventures.com/datasheets/BME280.pdf for the multibyte read. You specified timeout to 15 sec and you get the timeout after 15 secs. So it appears that the BME280 simply does not stop sending or it sends nothing including not a NOACK and Stop condition ...
HAL_I2C_Mem_Read sometimes causes problems, this depends on the slave https://community.arm.com/developer/ip-products/system/f/embedded-forum/7989/trouble-getting-values-with-i2c-using-hal_library
By the way with the
HAL.I2C.Mem_Read (This => Port.all,
Addr => I2C_Address,
Mem_Addr => 16#D0#,
Mem_Addr_Size => HAL.I2C.Memory_Size_8b,
Data => ID,
Status => Status,
Timeout => 15000);
you try to read 1 byte the chip identification number from register D0 cf http://www.embeddedadventures.com/datasheets/BME280.pdf page 26
I am running moodle on kubernetes with statefulsets of databases.
Moodle version : $version = 2018120303.14; // 20181203 = branching date YYYYMMDD - do not modify!
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '3.6.3+ (Build: 20190501)'; // Human-friendly version name
$branch = '36'; // This version's branch.
$maturity = MATURITY_STABLE; // This version's maturity level.
Error writing to database
Other information about this error
Debug info: Duplicate entry '1-12345678900' for key 'mdl_user_mneuse_uix'
INSERT INTO mdl_user (city,auth,policyagreed,idnumber,username,password,firstname,lastname,email,lang,confirmed,lastip,timecreated,timemodified,mnethostid) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
[array (
0 => '',
1 => 'wp2moodle',
2 => 1,
3 => '1584',
4 => '12345678900',
5 => 'a803bc70a48ce4568a9e85f7e1e30c58',
6 => 'Pedro',
7 => 'Marinelli',
8 => 'pedromarinelli#email.com',
9 => 'pt_br',
10 => 1,
11 => '177.192.193.143',
12 => 1537303059,
13 => 1537303059,
14 => '1',
)]
Error code: dmlwriteexception
Stack trace: line 489 of /lib/dml/moodle_database.php:
dml_write_exception thrown line 1329 of
/lib/dml/mysqli_native_moodle_database.php: call to
moodle_database->query_end() line 1375 of
/lib/dml/mysqli_native_moodle_database.php: call to
mysqli_native_moodle_database->insert_record_raw() line 232 of
/auth/wp2moodle/login.php: call to
mysqli_native_moodle_database->insert_record()
You are trying to add duplicate username into the database. Please check that, username your inserting has already existed.
Run this command which requires for moodle(3.1 and new version)
php admin/cli/mysql_collation.php --collation=utf8mb4_unicode_ci
I were trying to join igmp live streaming and play it in roku box. But it didn't worked.
Is it that we can not join multicast streaming in Roku boxes ?
If it is possible to do via HLS, then what could be the solution ?
I tried the reference in github at link : https://github.com/thetrime/trimeplay/blob/master/source/trimeplay.brs
Please refer the another code I were using as reference :
function SetupJoin()
ssdpAddress = "239.60.60.7:6607"
ssdpPort = 6607
timeout = 300 * 60 * 1000
groupAddr = CreateObject("roSocketAddress")
groupAddr.setAddress(ssdpAddress)
groupAddr.setPort(ssdpPort)
listenAddr = CreateObject("roSocketAddress")
listenAddr.setPort(ssdpPort)
listenAddr.setAddress("0.0.0.0")
listen = CreateObject("roDatagramSocket")
listen.setReuseAddr(true)
listen.setAddress(listenAddr)
result = listen.joinGroup(groupAddr)
listen.setMessagePort(canvas.GetMessagePort())
listen.notifyReadable(true)
numResponses= Wait_SSDP(listen, timeout)
? "Result : " result
? "SSDP Listen got"; numResponses; " responses"
end function
function Wait_SSDP(socket as Object, timeout as Integer) as Integer
numResponses = 0
elapsed = CreateObject("roTimespan")
remaining = timeout - elapsed.totalMilliseconds()
while remaining > 0
msg = wait(remaining, socket.getMessagePort())
if type(msg)="roSocketEvent"
if socket.isReadable()
results = socket.receiveStr(255)
print "SSDP Listen gets from "; socket.getReceivedFromAddress().getAddress(); ":"
print results
numResponses = numResponses + 1
end if
else
exit while 'enter code here
end if
remaining = timeout - elapsed.totalMilliseconds()
end while
return numResponses
end function
I'm not going to say that what you are trying to do is completely impossible, but it is impractical.
You would have to do something sort of like this:
Use roStreamSockets to collect the UDP data and write it to tmp:/ as an h.264 video file, probably as HLS chunks, then point the video playback component at it via .m3u8 files you also write on the fly. This would have to be done in Brightscript. I'm not sure that Brightscript is fast enough to do this. I'm not saying it is impossible to do it, but Roku does not natively play multicast or other UDP video stream formats.
The only officially supported video formats for live broadcast are HLS and Microsoft Smooth.
I have some perl code which I've written to get weather data/alerts from NOAA.
My code is pretty simple:
use Weather::NOAA::Alert;
use Data::Dumper;
$alert = Weather::NOAA::Alert->new(['TXC301']);
$events = $alert->get_events();
$alert->poll_events();
print Dumper($events);
# #url = (keys %{$VAR1->{'TXC301'}});
# $url = $VAR1->{'TXC301'};
$url = $events->{'TXC301'};
print "URL is $url\n";
# $expires= $events->{'TXC301'}->{$url}->{'expires'};
$expires= $events->{'TXC301'}->{'http://alerts.weather.gov/cap/wwacapget.php?x=TX12516CBE9400.FloodWarning.12516CC068C0TX.MAFFLWMAF.f21e7ce7cf8e930ab73a110c4d912576'}->{'expires'};
print "Expires: $expires\n";
The output:
$VAR1 = {
'TXC301' => {
'http://alerts.weather.gov/cap/wwacapget.php?x=TX12516CBE9400.FloodWarning.12516CC068C0TX.MAFFLWMAF.f21e7ce7cf8e930ab73a110c4d912576' => {
'certainty' => 'Likely',
'senderName' => 'NWS Midland-Odessa (Western Texas and Southeastern New Mexico)',
'urgency' => 'Expected',
'instruction' => 'A FLOOD WARNING MEANS THAT FLOODING IS IMMINENT OR HAS BEEN REPORTED.
STREAM RISES WILL BE SLOW AND FLASH FLOODING IS NOT EXPECTED.
HOWEVER... ALL INTERESTED PARTIES SHOULD TAKE NECESSARY PRECAUTIONS
IMMEDIATELY.
DO NOT DRIVE YOUR VEHICLE INTO AREAS WHERE THE WATER COVERS THE
ROADWAY. THE WATER DEPTH MAY BE TOO GREAT TO ALLOW YOUR CAR TO CROSS
SAFELY.',
'description' => 'THE NATIONAL WEATHER SERVICE IN MIDLAND HAS ISSUED A
FLOOD WARNING FOR...
SOUTHWESTERN LOVING COUNTY IN WEST TEXAS...
NORTHWESTERN WARD COUNTY IN WEST TEXAS...
NORTH CENTRAL REEVES COUNTY IN SOUTHWEST TEXAS...
UNTIL 300 PM CDT FRIDAY
AT 259 AM CDT...ROADS REMAIN CLOSED NEAR THE PECOS RIVER BETWEEN
RED BLUFF AND INTERSTATE 20 BECAUSE OF ELEVATED RIVER LEVELS DUE
TO RECENT RAINS. FLOODING WILL ALSO IMPACT THE CITY OF PECOS.',
'event' => 'Flood Warning',
'delete' => 0,
'category' => 'Met',
'severity' => 'Moderate',
'effective' => '2014-09-26T03:00:00-05:00',
'headline' => 'Flood Warning issued September 26 at 3:00AM CDT until September 26 at 3:00PM CDT by NWS Midland-Odessa',
'expires' => '2014-09-26T15:00:00-05:00'
}
}
};
URL is HASH(0x26384c0)
Expires: 2014-09-26T15:00:00-05:00
The TXC301 is a report identifier.
The output of the script will print all the values fetched from NOAA.
The goal is to store/return the 'expires' value.
I have lines commented out, which were attempts at achieving my goal.
The problem I'm having is getting the $url variable. I need this value in order to get my $expires value. The 2nd to last line in my code will correctly get the $expires value, but in order to do this I needed to hard code the URL into the line.
I'm trying to get the line directly above that (3rd to last) to work:
$expires= $events->{'TXC301'}->{$url}->{'expires'};
But this depends on the $url value to be stored.
I can't seem to figure out how to get the $url value.
My guesses:
#url = (keys %{$VAR1->{'TXC301'}});
$url = $VAR1->{'TXC301'};
$url = $events->{'TXC301'};
None of which work.
Any help would be great.
Thanks!
Regards,
Joseph Spenner
Given there is only one value for that level of hash ref, you could use values:
print +( values %{ $VAR1->{TXC301} } )[0]{expires}, "\n";
Outputs:
2014-09-26T15:00:00-05:00
Alternative to Data::Dumper
Also, on a separate issue, I would like to recommend the use of Data::Dump over the core library Data::Dumper.
The default settings and features for this alternative give superior output and enable one to analyze a data structure a lot quicker as demonstrated below:
$VAR1 = {
'TXC301' => {
'http://alerts.weather.gov/cap/wwacapget.php?x=TX12516CBE9400.FloodWarning.12516CC068C0TX.MAFFLWMAF.f21e7ce7cf8e930ab73a110c4d912576' => {
'certainty' => 'Likely',
'senderName' => 'NWS Midland-Odessa (Western Texas and Southeastern New Mexico)',
'urgency' => 'Expected',
'instruction' => 'A FLOOD WARNING MEANS THAT FLOODING IS IMMINENT OR HAS BEEN REPORTED.
STREAM RISES WILL BE SLOW AND FLASH FLOODING IS NOT EXPECTED.
HOWEVER... ALL INTERESTED PARTIES SHOULD TAKE NECESSARY PRECAUTIONS
IMMEDIATELY.
DO NOT DRIVE YOUR VEHICLE INTO AREAS WHERE THE WATER COVERS THE
ROADWAY. THE WATER DEPTH MAY BE TOO GREAT TO ALLOW YOUR CAR TO CROSS
SAFELY.',
'description' => 'THE NATIONAL WEATHER SERVICE IN MIDLAND HAS ISSUED A
FLOOD WARNING FOR...
SOUTHWESTERN LOVING COUNTY IN WEST TEXAS...
NORTHWESTERN WARD COUNTY IN WEST TEXAS...
NORTH CENTRAL REEVES COUNTY IN SOUTHWEST TEXAS...
UNTIL 300 PM CDT FRIDAY
AT 259 AM CDT...ROADS REMAIN CLOSED NEAR THE PECOS RIVER BETWEEN
RED BLUFF AND INTERSTATE 20 BECAUSE OF ELEVATED RIVER LEVELS DUE
TO RECENT RAINS. FLOODING WILL ALSO IMPACT THE CITY OF PECOS.',
'event' => 'Flood Warning',
'delete' => 0,
'category' => 'Met',
'severity' => 'Moderate',
'effective' => '2014-09-26T03:00:00-05:00',
'headline' => 'Flood Warning issued September 26 at 3:00AM CDT until September 26 at 3:00PM CDT by NWS Midland-Odessa',
'expires' => '2014-09-26T15:00:00-05:00'
}
}
};
use Data::Dump;
dd $VAR1;
Outputs:
{
TXC301 => {
"http://alerts.weather.gov/cap/wwacapget.php?x=TX12516CBE9400.FloodWarning.12516CC068C0TX.MAFFLWMAF.f21e7ce7cf8e930ab73a110c4d912576" => {
category => "Met",
certainty => "Likely",
delete => 0,
description => "THE NATIONAL WEATHER SERVICE IN MIDLAND HAS ISSUED A\n FLOOD WARNING FOR...\nSOUTHWESTERN LOVING COUNTY IN WEST TEXAS...\nNORTHWESTERN WARD COUNTY IN WEST TEXAS...\nNORTH CENTRAL REEVES COUNTY IN SOUTHWEST TEXAS...\n UNTIL 300 PM CDT FRIDAY\n AT 259 AM CDT...ROADS REMAIN CLOSED NEAR THE PECOS RIVER BETWEEN\nRED BLUFF AND INTERSTATE 20 BECAUSE OF ELEVATED RIVER LEVELS DUE\nTO RECENT RAINS. FLOODING WILL ALSO IMPACT THE CITY OF PECOS.",
effective => "2014-09-26T03:00:00-05:00",
event => "Flood Warning",
expires => "2014-09-26T15:00:00-05:00",
headline => "Flood Warning issued September 26 at 3:00AM CDT until September 26 at 3:00PM CDT by NWS Midland-Odessa",
instruction => "A FLOOD WARNING MEANS THAT FLOODING IS IMMINENT OR HAS BEEN REPORTED.\nSTREAM RISES WILL BE SLOW AND FLASH FLOODING IS NOT EXPECTED.\nHOWEVER... ALL INTERESTED PARTIES SHOULD TAKE NECESSARY PRECAUTIONS\nIMMEDIATELY.\nDO NOT DRIVE YOUR VEHICLE INTO AREAS WHERE THE WATER COVERS THE\nROADWAY. THE WATER DEPTH MAY BE TOO GREAT TO ALLOW YOUR CAR TO CROSS\nSAFELY.",
senderName => "NWS Midland-Odessa (Western Texas and Southeastern New Mexico)",
severity => "Moderate",
urgency => "Expected",
},
},
}
Ok, I was able to piece something together which worked:
use Weather::NOAA::Alert;
use Data::Dumper;
$alert = Weather::NOAA::Alert->new(['TXC301']);
$events = $alert->get_events();
$alert->poll_events();
Dumper($events);
print +( values %{ $events->{TXC301} } )[0]{expires}, "\n";
By changing $VAR1 to $events in the last line, I got rid of the error and got the exact output I needed.
Thanks for all the quick replies!
Regards,
Joseph Spenner
I am in the process of writing a GUI which will monitor if various measurements have been made on a weekly basis. I have written various other GUIs for updating measurements results each day onto a database. These GUIs use Tk::Date datewidget that allows me to toggle by days
my $datewidget = $f_filter->Date(-choices=>'today', -datefmt=>'%2d %2m %4y',
-fields=>'date', -varfmt=>'datehash',
-monthmenu=>1, -allarrows=>1,
-value=>'now', -command=>\&populate)->pack(-side=>'left');
This lets me use the up and down arrows to increment/decrement days, change months and year.
What I desire to do in the weekly GUI is have an up and down arrow that will toggle by week only. Eg this week would be 'Mon Nov 4 - Fri Nov 8', next week 'Mon Nov 11 to Fri Nov 15'
I would like to be able to go forwards and backwards several years.
Is there a simple way to do this in perl-Tk::Date or Date::Entry?
Tk::Date and Tk::DateEntry cannot do this out of the box. With Tk::Date, I can propose the following approach:
use -varfmt => 'unixtime' instead of datehash, because the latter does not work well with the ->configure(-value => ...) call used later
set -editable=>0 to remove all arrow buttons created by Tk::Date
create the inc/dec buttons yourself
and make the date calculations using DateTime (see the incweek subroutine here)
Something like the following could work:
use strict;
use Tk;
use Tk::Date;
my $mw = tkinit;
my $datewidget = $mw->Date(-choices=>'today', -datefmt=>'%2d %2m %4y',
-fields=>'date', -varfmt=>'unixtime',
-editable=>0,
-monthmenu=>1,
-value=>'now',
-command=>sub { warn "populate #_" })->pack(-side=>'left');
my $arrowframe = $mw->Frame->pack(-side => 'left');
{
no warnings 'once'; # because of INCBITMAP/DECBITMAP
$arrowframe->FireButton(-bitmap => $Tk::FireButton::INCBITMAP, -command => sub { incweek(+1) })->pack(-side => 'top');
$arrowframe->FireButton(-bitmap => $Tk::FireButton::DECBITMAP, -command => sub { incweek(-1) })->pack(-side => 'top');
}
MainLoop;
sub incweek {
my($inc) = #_;
use DateTime;
my $epoch = $datewidget->get;
my $dt = DateTime->from_epoch(epoch => $epoch);
$dt = $dt->add(weeks => $inc);
$datewidget->configure(-value => $dt->epoch);
}
__END__
Note that $datewidget->get returrns now the epoch time, but using DateTime you can easily convert this into y/m/d values.